summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
Diffstat (limited to 'Zend')
-rw-r--r--Zend/Zend.m42
-rw-r--r--Zend/bug69756.phpt12
-rw-r--r--Zend/tests/anon/006.phpt2
-rw-r--r--Zend/tests/anon/007.phpt2
-rw-r--r--Zend/tests/array_offset.phpt21
-rw-r--r--Zend/tests/array_type_hint_001.phpt2
-rw-r--r--Zend/tests/assert/expect_015.phpt6
-rw-r--r--Zend/tests/bug39003.phpt2
-rw-r--r--Zend/tests/bug42802.phpt2
-rw-r--r--Zend/tests/bug43332_1.phpt2
-rw-r--r--Zend/tests/bug68446.phpt2
-rw-r--r--Zend/tests/bug69551.phpt16
-rw-r--r--Zend/tests/bug69676.phpt19
-rw-r--r--Zend/tests/bug69732.phpt30
-rw-r--r--Zend/tests/bug69740.phpt28
-rw-r--r--Zend/tests/bug69754.phpt25
-rw-r--r--Zend/tests/bug69755.phpt8
-rw-r--r--Zend/tests/bug69758.phpt27
-rw-r--r--Zend/tests/bug69761.phpt15
-rw-r--r--Zend/tests/bug69767.phpt8
-rw-r--r--Zend/tests/bug69788.phpt8
-rw-r--r--Zend/tests/bug69805.phpt8
-rw-r--r--Zend/tests/bug69825.phpt30
-rw-r--r--Zend/tests/closure_027.phpt2
-rw-r--r--Zend/tests/gc_024.phpt2
-rw-r--r--Zend/tests/grammar/regression_001.phpt33
-rw-r--r--Zend/tests/grammar/regression_002.phpt22
-rw-r--r--Zend/tests/grammar/regression_003.phpt13
-rw-r--r--Zend/tests/grammar/regression_004.phpt15
-rw-r--r--Zend/tests/grammar/regression_005.phpt14
-rw-r--r--Zend/tests/grammar/regression_006.phpt30
-rw-r--r--Zend/tests/grammar/regression_007.phpt44
-rw-r--r--Zend/tests/grammar/regression_008.phpt21
-rw-r--r--Zend/tests/grammar/regression_009.phpt18
-rw-r--r--Zend/tests/grammar/regression_010.phpt14
-rw-r--r--Zend/tests/grammar/regression_011.phpt18
-rw-r--r--Zend/tests/grammar/regression_012.phpt13
-rw-r--r--Zend/tests/grammar/regression_013.phpt13
-rw-r--r--Zend/tests/grammar/semi_reserved_001.phpt209
-rw-r--r--Zend/tests/grammar/semi_reserved_002.phpt207
-rw-r--r--Zend/tests/grammar/semi_reserved_003.phpt210
-rw-r--r--Zend/tests/grammar/semi_reserved_004.phpt210
-rw-r--r--Zend/tests/grammar/semi_reserved_005.phpt207
-rw-r--r--Zend/tests/grammar/semi_reserved_006.phpt80
-rw-r--r--Zend/tests/grammar/semi_reserved_007.phpt37
-rw-r--r--Zend/tests/grammar/semi_reserved_008.phpt68
-rw-r--r--Zend/tests/grammar/semi_reserved_009.phpt25
-rw-r--r--Zend/tests/grammar/semi_reserved_010.phpt31
-rw-r--r--Zend/tests/loop_free_on_return.phpt16
-rw-r--r--Zend/tests/ns_071.phpt2
-rw-r--r--Zend/tests/ns_072.phpt2
-rw-r--r--Zend/tests/objects_022.phpt2
-rw-r--r--Zend/tests/return_types/028.phpt20
-rw-r--r--Zend/tests/typehints/explicit_weak_include_strict.phpt2
-rw-r--r--Zend/tests/typehints/strict_call_weak.phpt2
-rw-r--r--Zend/tests/typehints/strict_call_weak_explicit.phpt2
-rw-r--r--Zend/tests/typehints/weak_include_strict.phpt2
-rw-r--r--Zend/tests/variadic/closure_invoke.phpt17
-rw-r--r--Zend/tests/variadic/typehint_error.phpt2
-rw-r--r--Zend/zend.c6
-rw-r--r--Zend/zend_API.c182
-rw-r--r--Zend/zend_API.h46
-rw-r--r--Zend/zend_alloc.c1
-rw-r--r--Zend/zend_ast.c10
-rw-r--r--Zend/zend_ast.h1
-rw-r--r--Zend/zend_builtin_functions.c17
-rw-r--r--Zend/zend_closures.c5
-rw-r--r--Zend/zend_compile.c629
-rw-r--r--Zend/zend_compile.h23
-rw-r--r--Zend/zend_exceptions.c6
-rw-r--r--Zend/zend_execute.c202
-rw-r--r--Zend/zend_generators.c29
-rw-r--r--Zend/zend_globals.h9
-rw-r--r--Zend/zend_hash.c27
-rw-r--r--Zend/zend_hash.h20
-rw-r--r--Zend/zend_inheritance.c2
-rw-r--r--Zend/zend_ini_scanner.c2
-rw-r--r--Zend/zend_ini_scanner.l2
-rw-r--r--Zend/zend_language_parser.y97
-rw-r--r--Zend/zend_language_scanner.c1097
-rw-r--r--Zend/zend_language_scanner.h4
-rw-r--r--Zend/zend_language_scanner.l371
-rw-r--r--Zend/zend_long.h2
-rw-r--r--Zend/zend_object_handlers.c23
-rw-r--r--Zend/zend_objects.c10
-rw-r--r--Zend/zend_opcode.c47
-rw-r--r--Zend/zend_operators.c80
-rw-r--r--Zend/zend_operators.h3
-rw-r--r--Zend/zend_portability.h1
-rw-r--r--Zend/zend_types.h19
-rw-r--r--Zend/zend_virtual_cwd.c34
-rw-r--r--Zend/zend_virtual_cwd.h29
-rw-r--r--Zend/zend_vm_def.h1287
-rw-r--r--Zend/zend_vm_execute.h10172
-rw-r--r--Zend/zend_vm_gen.php25
-rw-r--r--Zend/zend_vm_opcodes.c4
-rw-r--r--Zend/zend_vm_opcodes.h2
97 files changed, 9698 insertions, 6730 deletions
diff --git a/Zend/Zend.m4 b/Zend/Zend.m4
index 868a04d91e..6104dc0bc9 100644
--- a/Zend/Zend.m4
+++ b/Zend/Zend.m4
@@ -462,4 +462,4 @@ if test "$ZEND_GCC_GLOBAL_REGS" = "yes"; then
else
HAVE_GCC_GLOBAL_REGS=no
fi
-AC_MSG_RESULT(ZEND_GCC_GLOBAL_REGS)
+AC_MSG_RESULT($ZEND_GCC_GLOBAL_REGS)
diff --git a/Zend/bug69756.phpt b/Zend/bug69756.phpt
new file mode 100644
index 0000000000..ca638fb2d6
--- /dev/null
+++ b/Zend/bug69756.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Fixed bug #69756 (Fatal error: Nesting level too deep - recursive dependency? with ===).
+--FILE--
+<?php
+$arr = range(1, 2);
+foreach($arr as &$item ) {
+ var_dump($arr === array(1, 2));
+}
+?>
+--EXPECT--
+bool(true)
+bool(true)
diff --git a/Zend/tests/anon/006.phpt b/Zend/tests/anon/006.phpt
index e5dc1226d8..2b8888c497 100644
--- a/Zend/tests/anon/006.phpt
+++ b/Zend/tests/anon/006.phpt
@@ -10,6 +10,6 @@ namespace {
var_dump ($hello);
}
--EXPECTF--
-object(lone\class@%s)#1 (0) {
+object(class@%s)#1 (0) {
}
diff --git a/Zend/tests/anon/007.phpt b/Zend/tests/anon/007.phpt
index 12f4da6653..59d2441760 100644
--- a/Zend/tests/anon/007.phpt
+++ b/Zend/tests/anon/007.phpt
@@ -18,6 +18,6 @@ namespace lone {
new Outer();
}
--EXPECTF--
-object(lone\class@%s)#2 (0) {
+object(class@%s)#2 (0) {
}
diff --git a/Zend/tests/array_offset.phpt b/Zend/tests/array_offset.phpt
new file mode 100644
index 0000000000..76c25f9298
--- /dev/null
+++ b/Zend/tests/array_offset.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Ensure "undefined offset" notice formats message corectly when undefined key is negative
+--FILE--
+<?php
+
+[][-1];
+[][-1.1];
+(new ArrayObject)[-1];
+(new ArrayObject)[-1.1];
+
+echo "Done\n";
+?>
+--EXPECTF--
+Notice: Undefined offset: -1 in %s on line 3
+
+Notice: Undefined offset: -1 in %s on line 4
+
+Notice: Undefined offset: -1 in %s on line 5
+
+Notice: Undefined offset: -1 in %s on line 6
+Done
diff --git a/Zend/tests/array_type_hint_001.phpt b/Zend/tests/array_type_hint_001.phpt
index 474ffa8e59..2b473c56b4 100644
--- a/Zend/tests/array_type_hint_001.phpt
+++ b/Zend/tests/array_type_hint_001.phpt
@@ -14,6 +14,6 @@ foo(123);
Fatal error: Uncaught TypeError: Argument 1 passed to foo() must be of the type array, integer given, called in %sarray_type_hint_001.php on line 7 and defined in %sarray_type_hint_001.php:2
Stack trace:
-#0 %s(%d): foo()
+#0 %s(%d): foo(123)
#1 {main}
thrown in %sarray_type_hint_001.php on line 2
diff --git a/Zend/tests/assert/expect_015.phpt b/Zend/tests/assert/expect_015.phpt
index 80f1bd8aa8..030913f7f9 100644
--- a/Zend/tests/assert/expect_015.phpt
+++ b/Zend/tests/assert/expect_015.phpt
@@ -144,12 +144,6 @@ assert(0 && ($a = function () {
?>
--EXPECTF--
-Warning: Unsupported declare 'A' in %sexpect_015.php on line %d
-
-Warning: Unsupported declare 'B' in %sexpect_015.php on line %d
-
-Warning: Unsupported declare 'C' in %sexpect_015.php on line %d
-
Warning: assert(): assert(0 && ($a = function () {
global $a;
global $$b;
diff --git a/Zend/tests/bug39003.phpt b/Zend/tests/bug39003.phpt
index f4f9e4d9b6..add14512c8 100644
--- a/Zend/tests/bug39003.phpt
+++ b/Zend/tests/bug39003.phpt
@@ -23,6 +23,6 @@ echo "Done\n";
--EXPECTF--
Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of OtherClassName, instance of ClassName given, called in %s on line %d and defined in %s:%d
Stack trace:
-#0 %s(%d): test()
+#0 %s(%d): test(Object(ClassName))
#1 {main}
thrown in %s on line %d
diff --git a/Zend/tests/bug42802.phpt b/Zend/tests/bug42802.phpt
index 6dad5feccb..3b00408e01 100644
--- a/Zend/tests/bug42802.phpt
+++ b/Zend/tests/bug42802.phpt
@@ -39,6 +39,6 @@ ok
Fatal error: Uncaught TypeError: Argument 1 passed to foo\test5() must be an instance of bar, instance of foo\bar given, called in %sbug42802.php on line %d and defined in %sbug42802.php:%d
Stack trace:
-#0 %s(%d): foo\test5()
+#0 %s(%d): foo\test5(Object(foo\bar))
#1 {main}
thrown in %sbug42802.php on line %d
diff --git a/Zend/tests/bug43332_1.phpt b/Zend/tests/bug43332_1.phpt
index 5fe734cfea..fc035ab2b6 100644
--- a/Zend/tests/bug43332_1.phpt
+++ b/Zend/tests/bug43332_1.phpt
@@ -14,6 +14,6 @@ $foo->bar(new \stdclass); // Error, ok!
--EXPECTF--
Fatal error: Uncaught TypeError: Argument 1 passed to foobar\foo::bar() must be an instance of foobar\foo, instance of stdClass given, called in %sbug43332_1.php on line 10 and defined in %sbug43332_1.php:5
Stack trace:
-#0 %s(%d): foobar\foo->bar()
+#0 %s(%d): foobar\foo->bar(Object(stdClass))
#1 {main}
thrown in %sbug43332_1.php on line 5
diff --git a/Zend/tests/bug68446.phpt b/Zend/tests/bug68446.phpt
index 2dad15d411..994699e5de 100644
--- a/Zend/tests/bug68446.phpt
+++ b/Zend/tests/bug68446.phpt
@@ -34,7 +34,7 @@ array(1) {
Fatal error: Uncaught TypeError: Argument 1 passed to a() must be of the type array, null given, called in %s on line %d and defined in %s:%d
Stack trace:
-#0 %s(%d): a()
+#0 %s(%d): a(NULL)
#1 {main}
thrown in %s on line %d
diff --git a/Zend/tests/bug69551.phpt b/Zend/tests/bug69551.phpt
new file mode 100644
index 0000000000..096852a2fa
--- /dev/null
+++ b/Zend/tests/bug69551.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Bug #69551 - parse_ini_file() and parse_ini_string() segmentation fault
+--FILE--
+<?php
+$ini = <<<INI
+[Network.eth0]
+SubnetMask = "
+"
+INI;
+$settings = parse_ini_string($ini, false, INI_SCANNER_RAW);
+var_dump($settings);
+?>
+--EXPECTF--
+Warning: syntax error, unexpected '"' in Unknown on line %d
+ in %s on line %d
+bool(false)
diff --git a/Zend/tests/bug69676.phpt b/Zend/tests/bug69676.phpt
new file mode 100644
index 0000000000..54b9d40047
--- /dev/null
+++ b/Zend/tests/bug69676.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Bug #69676: Resolution of self::FOO in class constants not correct
+--FILE--
+<?php
+class A {
+ const myConst = "const in A";
+ const myDynConst = self::myConst;
+}
+
+class B extends A {
+ const myConst = "const in B";
+}
+
+var_dump(B::myDynConst);
+var_dump(A::myDynConst);
+?>
+--EXPECT--
+string(10) "const in A"
+string(10) "const in A"
diff --git a/Zend/tests/bug69732.phpt b/Zend/tests/bug69732.phpt
new file mode 100644
index 0000000000..bc6206d113
--- /dev/null
+++ b/Zend/tests/bug69732.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Bug #69732 (can induce segmentation fault with basic php code)
+--FILE--
+<?php
+class wpq {
+ private $unreferenced;
+
+ public function __get($name) {
+ return $this->$name . "XXX";
+ }
+}
+
+function ret_assoc() {
+ $x = "XXX";
+ return array('foo' => 'bar', $x);
+}
+
+$wpq = new wpq;
+$wpq->interesting =& ret_assoc();
+$x = $wpq->interesting;
+printf("%s\n", $x);
+--EXPECTF--
+Notice: Undefined property: wpq::$interesting in %sbug69732.php on line 6
+
+Notice: Indirect modification of overloaded property wpq::$interesting has no effect in %sbug69732.php on line 16
+
+Notice: Only variables should be assigned by reference in %sbug69732.php on line 16
+
+Notice: Undefined property: wpq::$interesting in %sbug69732.php on line 6
+XXX
diff --git a/Zend/tests/bug69740.phpt b/Zend/tests/bug69740.phpt
new file mode 100644
index 0000000000..c8910b22d8
--- /dev/null
+++ b/Zend/tests/bug69740.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Bug #69740: finally in generator (yield) swallows exception in iteration
+--FILE--
+<?php
+
+function generate() {
+ try {
+ yield 1;
+ yield 2;
+ } finally {
+ echo "finally\n";
+ }
+}
+
+foreach (generate() as $i) {
+ echo $i, "\n";
+ throw new Exception();
+}
+
+?>
+--EXPECTF--
+1
+finally
+
+Fatal error: Uncaught Exception in %s:%d
+Stack trace:
+#0 {main}
+ thrown in %s on line %d
diff --git a/Zend/tests/bug69754.phpt b/Zend/tests/bug69754.phpt
new file mode 100644
index 0000000000..be55ae2b78
--- /dev/null
+++ b/Zend/tests/bug69754.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Bug #69754 (Use of ::class inside array causes compile error)
+--FILE--
+<?php
+
+class Example {
+ public function test() {
+ var_dump(static::class);
+ var_dump(static::class . 'IsAwesome');
+ var_dump(static::class . date('Ymd'));
+ var_dump([static::class]);
+ }
+}
+
+(new Example)->test();
+
+?>
+--EXPECTF--
+string(7) "Example"
+string(16) "ExampleIsAwesome"
+string(15) "Example%d"
+array(1) {
+ [0]=>
+ string(7) "Example"
+}
diff --git a/Zend/tests/bug69755.phpt b/Zend/tests/bug69755.phpt
new file mode 100644
index 0000000000..67c0ed3383
--- /dev/null
+++ b/Zend/tests/bug69755.phpt
@@ -0,0 +1,8 @@
+--TEST--
+Bug #69755: segfault in ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER
+--FILE--
+<?php
+c . 10;
+?>
+--EXPECTF--
+Notice: Use of undefined constant c - assumed 'c' in %sbug69755.php on line 2
diff --git a/Zend/tests/bug69758.phpt b/Zend/tests/bug69758.phpt
new file mode 100644
index 0000000000..f0b3588139
--- /dev/null
+++ b/Zend/tests/bug69758.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #69758 (Item added to array not being removed by array_pop/shift)
+--FILE--
+<?php
+$tokens = array();
+$conditions = array();
+for ($i = 0; $i <= 10; $i++) {
+ $tokens[$i] = $conditions;
+
+ // First integer must be less than 8
+ // and second must be 8, 9 or 10
+ if ($i !== 0 && $i !== 8) {
+ continue;
+ }
+
+ // Add condition and then pop off straight away.
+ // Can also use array_shift() here.
+ $conditions[$i] = true;
+ $oldCondition = array_pop($conditions);
+}
+
+// Conditions should be empty.
+var_dump($conditions);
+?>
+--EXPECT--
+array(0) {
+}
diff --git a/Zend/tests/bug69761.phpt b/Zend/tests/bug69761.phpt
new file mode 100644
index 0000000000..4b7e2787d8
--- /dev/null
+++ b/Zend/tests/bug69761.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Bug #69761 (Serialization of anonymous classes should be prevented)
+--FILE--
+<?php
+$instance = new class('foo') {
+ public function __construct($i) {
+ }
+};
+var_dump(serialize($instance));
+?>
+--EXPECTF--
+Fatal error: Uncaught Exception: Serialization of 'class@%s' is not allowed in %sbug69761.php:%d
+Stack trace:
+#0 %sbug69761.php(%d): serialize(Object(class@%s
+ thrown in %sbug69761.php on line %d
diff --git a/Zend/tests/bug69767.phpt b/Zend/tests/bug69767.phpt
new file mode 100644
index 0000000000..cf4d4e7f93
--- /dev/null
+++ b/Zend/tests/bug69767.phpt
@@ -0,0 +1,8 @@
+--TEST--
+Bug #69767 (Default parameter value with wrong type segfaults)
+--FILE--
+<?php
+function foo(String $bar = 0) {}
+?>
+--EXPECTF--
+Fatal error: Default value for parameters with a string type hint can only be string or NULL in %sbug69767.php on line %d
diff --git a/Zend/tests/bug69788.phpt b/Zend/tests/bug69788.phpt
new file mode 100644
index 0000000000..e48486625f
--- /dev/null
+++ b/Zend/tests/bug69788.phpt
@@ -0,0 +1,8 @@
+--TEST--
+Bug #69788: Malformed script causes Uncaught EngineException in php-cgi, valgrind SIGILL
+--FILE--
+<?php [t.[]]; ?>
+--EXPECTF--
+Notice: Array to string conversion in %s on line %d
+
+Notice: Use of undefined constant t - assumed 't' in %s on line %d
diff --git a/Zend/tests/bug69805.phpt b/Zend/tests/bug69805.phpt
new file mode 100644
index 0000000000..c3ca62dc11
--- /dev/null
+++ b/Zend/tests/bug69805.phpt
@@ -0,0 +1,8 @@
+--TEST--
+Bug #69805 (null ptr deref and seg fault in zend_resolve_class_name)
+--FILE--
+<?php
+class p{public function c(){(0)::t;}}?>
+?>
+--EXPECTF--
+Fatal error: Illegal class name in %sbug69805.php on line %d
diff --git a/Zend/tests/bug69825.phpt b/Zend/tests/bug69825.phpt
new file mode 100644
index 0000000000..1349dee5ae
--- /dev/null
+++ b/Zend/tests/bug69825.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Bug #69825 (Short-circuiting failure)
+--FILE--
+<?php
+
+print "AND\n";
+var_dump(0 && 1);
+var_dump(0 && 0);
+var_dump(1 && 0);
+var_dump(1 && 1);
+
+print "OR\n";
+var_dump(0 || 1);
+var_dump(0 || 0);
+var_dump(1 || 0);
+var_dump(1 || 1);
+
+?>
+--EXPECT--
+AND
+bool(false)
+bool(false)
+bool(false)
+bool(true)
+OR
+bool(true)
+bool(false)
+bool(true)
+bool(true)
+
diff --git a/Zend/tests/closure_027.phpt b/Zend/tests/closure_027.phpt
index a56b78013c..db42ae9307 100644
--- a/Zend/tests/closure_027.phpt
+++ b/Zend/tests/closure_027.phpt
@@ -30,6 +30,6 @@ NULL
Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of Closure, instance of stdClass given, called in %s on line %d and defined in %s:%d
Stack trace:
-#0 %s(%d): test()
+#0 %s(%d): test(Object(stdClass))
#1 {main}
thrown in %s on line %d
diff --git a/Zend/tests/gc_024.phpt b/Zend/tests/gc_024.phpt
index 9a2ceb88f5..ca78da63d3 100644
--- a/Zend/tests/gc_024.phpt
+++ b/Zend/tests/gc_024.phpt
@@ -13,5 +13,5 @@ var_dump(gc_collect_cycles());
echo "ok\n";
?>
--EXPECT--
-int(1)
+int(2)
ok
diff --git a/Zend/tests/grammar/regression_001.phpt b/Zend/tests/grammar/regression_001.phpt
new file mode 100644
index 0000000000..73d5eacdf6
--- /dev/null
+++ b/Zend/tests/grammar/regression_001.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Test to check static method calls syntax regression
+--FILE--
+<?php
+
+class Foo {
+ public static function function(){ echo __METHOD__, PHP_EOL; }
+}
+
+Foo::function();
+
+Foo::
+function();
+
+Foo::
+ function();
+
+
+Foo::
+ function(
+
+);
+
+echo "\nDone\n";
+
+--EXPECTF--
+
+Foo::function
+Foo::function
+Foo::function
+Foo::function
+
+Done
diff --git a/Zend/tests/grammar/regression_002.phpt b/Zend/tests/grammar/regression_002.phpt
new file mode 100644
index 0000000000..dd307c99d8
--- /dev/null
+++ b/Zend/tests/grammar/regression_002.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test to ensure ::class still works
+--FILE--
+<?php
+
+class Foo {}
+
+var_dump(Foo::class);
+
+var_dump(Foo:: class);
+
+var_dump(Foo:: CLASS);
+
+var_dump(Foo::
+
+CLASS);
+
+--EXPECTF--
+string(3) "Foo"
+string(3) "Foo"
+string(3) "Foo"
+string(3) "Foo"
diff --git a/Zend/tests/grammar/regression_003.phpt b/Zend/tests/grammar/regression_003.phpt
new file mode 100644
index 0000000000..e475754ccd
--- /dev/null
+++ b/Zend/tests/grammar/regression_003.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Test to ensure ::class is still reserved in obj scope
+--FILE--
+<?php
+
+class Obj
+{
+ const CLASS = 'class';
+}
+
+?>
+--EXPECTF--
+Fatal error: A class constant must not be called 'class'; it is reserved for class name fetching in %s on line %d
diff --git a/Zend/tests/grammar/regression_004.phpt b/Zend/tests/grammar/regression_004.phpt
new file mode 100644
index 0000000000..e95674d8c9
--- /dev/null
+++ b/Zend/tests/grammar/regression_004.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Test possible function naming regression on procedural scope
+--FILE--
+<?php
+
+class Obj
+{
+ function echo(){} // valid
+ function return(){} // valid
+}
+
+function echo(){} // not valid
+
+--EXPECTF--
+Parse error: syntax error, unexpected 'echo' (T_ECHO), expecting identifier (T_STRING) or '(' in %s on line 9
diff --git a/Zend/tests/grammar/regression_005.phpt b/Zend/tests/grammar/regression_005.phpt
new file mode 100644
index 0000000000..7704375d6e
--- /dev/null
+++ b/Zend/tests/grammar/regression_005.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Test possible constant naming regression on procedural scope
+--FILE--
+<?php
+
+class Obj
+{
+ const return = 'yep';
+}
+
+const return = 'nope';
+
+--EXPECTF--
+Parse error: syntax error, unexpected 'return' (T_RETURN), expecting identifier (T_STRING) in %s on line 8
diff --git a/Zend/tests/grammar/regression_006.phpt b/Zend/tests/grammar/regression_006.phpt
new file mode 100644
index 0000000000..6aae0ba24b
--- /dev/null
+++ b/Zend/tests/grammar/regression_006.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test to ensure const list syntax declaration works
+--FILE--
+<?php
+
+class Obj
+{
+ const DECLARE = 'declare',
+ RETURN = 'return',
+ FUNCTION = 'function',
+ USE = 'use';
+}
+
+echo Obj::DECLARE, PHP_EOL;
+echo Obj::RETURN, PHP_EOL;
+echo Obj::FUNCTION, PHP_EOL;
+echo Obj::USE, PHP_EOL;
+echo Obj::
+
+ USE, PHP_EOL;
+echo "\nDone\n";
+
+--EXPECTF--
+declare
+return
+function
+use
+use
+
+Done
diff --git a/Zend/tests/grammar/regression_007.phpt b/Zend/tests/grammar/regression_007.phpt
new file mode 100644
index 0000000000..92b22531a4
--- /dev/null
+++ b/Zend/tests/grammar/regression_007.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Test to ensure semi reserved words allow deference
+--FILE--
+<?php
+
+class Foo {
+ const use = 'yay';
+
+ public static function new() {
+ echo __METHOD__, PHP_EOL;
+ return new static();
+ }
+
+ public function self() {
+ echo __METHOD__, PHP_EOL;
+ return $this;
+ }
+}
+
+Foo::new()::new()::new();
+
+var_dump(
+ (new Foo)->self()::new()->self()->self()::use
+);
+
+Foo::{'new'}();
+
+var_dump(Foo::use);
+
+echo "\nDone\n";
+
+--EXPECTF--
+Foo::new
+Foo::new
+Foo::new
+Foo::self
+Foo::new
+Foo::self
+Foo::self
+string(3) "yay"
+Foo::new
+string(3) "yay"
+
+Done
diff --git a/Zend/tests/grammar/regression_008.phpt b/Zend/tests/grammar/regression_008.phpt
new file mode 100644
index 0000000000..7741ed036c
--- /dev/null
+++ b/Zend/tests/grammar/regression_008.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Test to check regressions on string interpolation with class members access
+--FILE--
+<?php
+
+class Friday {
+ public $require = "fun";
+}
+
+$friday = new Friday;
+
+echo "$friday->require ($friday->require) {$friday->require}", PHP_EOL;
+
+echo "\nDone\n";
+
+
+--EXPECTF--
+
+fun (fun) fun
+
+Done
diff --git a/Zend/tests/grammar/regression_009.phpt b/Zend/tests/grammar/regression_009.phpt
new file mode 100644
index 0000000000..589d90316b
--- /dev/null
+++ b/Zend/tests/grammar/regression_009.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Test to check regressions on use statements and lexer state
+--FILE--
+<?php
+
+use A\B\C\D;
+
+class Foo
+{
+ private static $foo;
+
+}
+
+echo PHP_EOL, "Done", PHP_EOL;
+
+--EXPECTF--
+
+Done
diff --git a/Zend/tests/grammar/regression_010.phpt b/Zend/tests/grammar/regression_010.phpt
new file mode 100644
index 0000000000..5dc90f288a
--- /dev/null
+++ b/Zend/tests/grammar/regression_010.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Test to check regressions on T_IMPLEMENTS followed by a T_NS_SEPARATOR
+--FILE--
+<?php
+
+interface A{}
+
+class B implements\A {}
+
+echo "Done", PHP_EOL;
+
+--EXPECTF--
+
+Done
diff --git a/Zend/tests/grammar/regression_011.phpt b/Zend/tests/grammar/regression_011.phpt
new file mode 100644
index 0000000000..c79c077187
--- /dev/null
+++ b/Zend/tests/grammar/regression_011.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Testing instantiation using namespace:: prefix
+--FILE--
+<?php
+
+namespace foo;
+
+class bar {
+}
+
+class_alias('foo\bar', 'foo\baz');
+
+var_dump(new namespace\baz);
+
+?>
+--EXPECTF--
+object(foo\bar)#%d (0) {
+}
diff --git a/Zend/tests/grammar/regression_012.phpt b/Zend/tests/grammar/regression_012.phpt
new file mode 100644
index 0000000000..3b4925afa6
--- /dev/null
+++ b/Zend/tests/grammar/regression_012.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Testing for regression on const list syntax and arrays
+--FILE--
+<?php
+
+class A {
+ const A = [1, FOREACH];
+}
+
+?>
+--EXPECTF--
+
+Parse error: syntax error, unexpected 'FOREACH' (T_FOREACH), expecting ']' in %s on line %d
diff --git a/Zend/tests/grammar/regression_013.phpt b/Zend/tests/grammar/regression_013.phpt
new file mode 100644
index 0000000000..1c60ffc273
--- /dev/null
+++ b/Zend/tests/grammar/regression_013.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Testing for regression with encapsed variables in class declaration context
+--FILE--
+<?php
+
+class A { function foo() { "{${$a}}"; } function list() {} }
+
+echo "Done", PHP_EOL;
+
+?>
+--EXPECTF--
+
+Done
diff --git a/Zend/tests/grammar/semi_reserved_001.phpt b/Zend/tests/grammar/semi_reserved_001.phpt
new file mode 100644
index 0000000000..c6bfd46611
--- /dev/null
+++ b/Zend/tests/grammar/semi_reserved_001.phpt
@@ -0,0 +1,209 @@
+--TEST--
+Test semi-reserved words as class methods
+--FILE--
+<?php
+
+class Obj
+{
+ function empty(){ echo __METHOD__, PHP_EOL; }
+ function callable(){ echo __METHOD__, PHP_EOL; }
+ function trait(){ echo __METHOD__, PHP_EOL; }
+ function extends(){ echo __METHOD__, PHP_EOL; }
+ function implements(){ echo __METHOD__, PHP_EOL; }
+ function const(){ echo __METHOD__, PHP_EOL; }
+ function enddeclare(){ echo __METHOD__, PHP_EOL; }
+ function endfor(){ echo __METHOD__, PHP_EOL; }
+ function endforeach(){ echo __METHOD__, PHP_EOL; }
+ function endif(){ echo __METHOD__, PHP_EOL; }
+ function endwhile(){ echo __METHOD__, PHP_EOL; }
+ function and(){ echo __METHOD__, PHP_EOL; }
+ function global(){ echo __METHOD__, PHP_EOL; }
+ function goto(){ echo __METHOD__, PHP_EOL; }
+ function instanceof(){ echo __METHOD__, PHP_EOL; }
+ function insteadof(){ echo __METHOD__, PHP_EOL; }
+ function interface(){ echo __METHOD__, PHP_EOL; }
+ function new(){ echo __METHOD__, PHP_EOL; }
+ function or(){ echo __METHOD__, PHP_EOL; }
+ function xor(){ echo __METHOD__, PHP_EOL; }
+ function try(){ echo __METHOD__, PHP_EOL; }
+ function use(){ echo __METHOD__, PHP_EOL; }
+ function var(){ echo __METHOD__, PHP_EOL; }
+ function exit(){ echo __METHOD__, PHP_EOL; }
+ function list(){ echo __METHOD__, PHP_EOL; }
+ function clone(){ echo __METHOD__, PHP_EOL; }
+ function include(){ echo __METHOD__, PHP_EOL; }
+ function include_once(){ echo __METHOD__, PHP_EOL; }
+ function throw(){ echo __METHOD__, PHP_EOL; }
+ function array(){ echo __METHOD__, PHP_EOL; }
+ function print(){ echo __METHOD__, PHP_EOL; }
+ function echo(){ echo __METHOD__, PHP_EOL; }
+ function require(){ echo __METHOD__, PHP_EOL; }
+ function require_once(){ echo __METHOD__, PHP_EOL; }
+ function return(){ echo __METHOD__, PHP_EOL; }
+ function else(){ echo __METHOD__, PHP_EOL; }
+ function elseif(){ echo __METHOD__, PHP_EOL; }
+ function default(){ echo __METHOD__, PHP_EOL; }
+ function break(){ echo __METHOD__, PHP_EOL; }
+ function continue(){ echo __METHOD__, PHP_EOL; }
+ function switch(){ echo __METHOD__, PHP_EOL; }
+ function yield(){ echo __METHOD__, PHP_EOL; }
+ function function(){ echo __METHOD__, PHP_EOL; }
+ function if(){ echo __METHOD__, PHP_EOL; }
+ function endswitch(){ echo __METHOD__, PHP_EOL; }
+ function finally(){ echo __METHOD__, PHP_EOL; }
+ function for(){ echo __METHOD__, PHP_EOL; }
+ function foreach(){ echo __METHOD__, PHP_EOL; }
+ function declare(){ echo __METHOD__, PHP_EOL; }
+ function case(){ echo __METHOD__, PHP_EOL; }
+ function do(){ echo __METHOD__, PHP_EOL; }
+ function while(){ echo __METHOD__, PHP_EOL; }
+ function as(){ echo __METHOD__, PHP_EOL; }
+ function catch(){ echo __METHOD__, PHP_EOL; }
+ function die(){ echo __METHOD__, PHP_EOL; }
+ function self(){ echo __METHOD__, PHP_EOL; }
+ function parent(){ echo __METHOD__, PHP_EOL; }
+ function public(){ echo __METHOD__, PHP_EOL; }
+ function protected(){ echo __METHOD__, PHP_EOL; }
+ function private(){ echo __METHOD__, PHP_EOL; }
+ function static(){ echo __METHOD__, PHP_EOL; }
+ function abstract(){ echo __METHOD__, PHP_EOL; }
+ function final(){ echo __METHOD__, PHP_EOL; }
+ function class(){ echo __METHOD__, PHP_EOL; }
+}
+
+$obj = new Obj;
+
+$obj->empty();
+$obj->callable();
+$obj->trait();
+$obj->extends();
+$obj->implements();
+$obj->const();
+$obj->enddeclare();
+$obj->endfor();
+$obj->endforeach();
+$obj->endif();
+$obj->endwhile();
+$obj->and();
+$obj->global();
+$obj->goto();
+$obj->instanceof();
+$obj->insteadof();
+$obj->interface();
+$obj->new();
+$obj->or();
+$obj->xor();
+$obj->try();
+$obj->use();
+$obj->var();
+$obj->exit();
+$obj->list();
+$obj->clone();
+$obj->include();
+$obj->include_once();
+$obj->throw();
+$obj->array();
+$obj->print();
+$obj->echo();
+$obj->require();
+$obj->require_once();
+$obj->return();
+$obj->else();
+$obj->elseif();
+$obj->default();
+$obj->break();
+$obj->continue();
+$obj->switch();
+$obj->yield();
+$obj->function();
+$obj->if();
+$obj->endswitch();
+$obj->finally();
+$obj->for();
+$obj->foreach();
+$obj->declare();
+$obj->case();
+$obj->do();
+$obj->while();
+$obj->as();
+$obj->catch();
+$obj->die();
+$obj->self();
+$obj->parent();
+$obj->public();
+$obj->protected();
+$obj->private();
+$obj->static();
+$obj->abstract();
+$obj->final();
+$obj->class();
+
+echo "\nDone\n";
+
+--EXPECTF--
+Obj::empty
+Obj::callable
+Obj::trait
+Obj::extends
+Obj::implements
+Obj::const
+Obj::enddeclare
+Obj::endfor
+Obj::endforeach
+Obj::endif
+Obj::endwhile
+Obj::and
+Obj::global
+Obj::goto
+Obj::instanceof
+Obj::insteadof
+Obj::interface
+Obj::new
+Obj::or
+Obj::xor
+Obj::try
+Obj::use
+Obj::var
+Obj::exit
+Obj::list
+Obj::clone
+Obj::include
+Obj::include_once
+Obj::throw
+Obj::array
+Obj::print
+Obj::echo
+Obj::require
+Obj::require_once
+Obj::return
+Obj::else
+Obj::elseif
+Obj::default
+Obj::break
+Obj::continue
+Obj::switch
+Obj::yield
+Obj::function
+Obj::if
+Obj::endswitch
+Obj::finally
+Obj::for
+Obj::foreach
+Obj::declare
+Obj::case
+Obj::do
+Obj::while
+Obj::as
+Obj::catch
+Obj::die
+Obj::self
+Obj::parent
+Obj::public
+Obj::protected
+Obj::private
+Obj::static
+Obj::abstract
+Obj::final
+Obj::class
+
+Done
diff --git a/Zend/tests/grammar/semi_reserved_002.phpt b/Zend/tests/grammar/semi_reserved_002.phpt
new file mode 100644
index 0000000000..b2c20028ca
--- /dev/null
+++ b/Zend/tests/grammar/semi_reserved_002.phpt
@@ -0,0 +1,207 @@
+--TEST--
+Test semi-reserved words as static class methods
+--FILE--
+<?php
+
+class Obj
+{
+ static function empty(){ echo __METHOD__, PHP_EOL; }
+ static function callable(){ echo __METHOD__, PHP_EOL; }
+ static function trait(){ echo __METHOD__, PHP_EOL; }
+ static function extends(){ echo __METHOD__, PHP_EOL; }
+ static function implements(){ echo __METHOD__, PHP_EOL; }
+ static function const(){ echo __METHOD__, PHP_EOL; }
+ static function enddeclare(){ echo __METHOD__, PHP_EOL; }
+ static function endfor(){ echo __METHOD__, PHP_EOL; }
+ static function endforeach(){ echo __METHOD__, PHP_EOL; }
+ static function endif(){ echo __METHOD__, PHP_EOL; }
+ static function endwhile(){ echo __METHOD__, PHP_EOL; }
+ static function and(){ echo __METHOD__, PHP_EOL; }
+ static function global(){ echo __METHOD__, PHP_EOL; }
+ static function goto(){ echo __METHOD__, PHP_EOL; }
+ static function instanceof(){ echo __METHOD__, PHP_EOL; }
+ static function insteadof(){ echo __METHOD__, PHP_EOL; }
+ static function interface(){ echo __METHOD__, PHP_EOL; }
+ static function new(){ echo __METHOD__, PHP_EOL; }
+ static function or(){ echo __METHOD__, PHP_EOL; }
+ static function xor(){ echo __METHOD__, PHP_EOL; }
+ static function try(){ echo __METHOD__, PHP_EOL; }
+ static function use(){ echo __METHOD__, PHP_EOL; }
+ static function var(){ echo __METHOD__, PHP_EOL; }
+ static function exit(){ echo __METHOD__, PHP_EOL; }
+ static function list(){ echo __METHOD__, PHP_EOL; }
+ static function clone(){ echo __METHOD__, PHP_EOL; }
+ static function include(){ echo __METHOD__, PHP_EOL; }
+ static function include_once(){ echo __METHOD__, PHP_EOL; }
+ static function throw(){ echo __METHOD__, PHP_EOL; }
+ static function array(){ echo __METHOD__, PHP_EOL; }
+ static function print(){ echo __METHOD__, PHP_EOL; }
+ static function echo(){ echo __METHOD__, PHP_EOL; }
+ static function require(){ echo __METHOD__, PHP_EOL; }
+ static function require_once(){ echo __METHOD__, PHP_EOL; }
+ static function return(){ echo __METHOD__, PHP_EOL; }
+ static function else(){ echo __METHOD__, PHP_EOL; }
+ static function elseif(){ echo __METHOD__, PHP_EOL; }
+ static function default(){ echo __METHOD__, PHP_EOL; }
+ static function break(){ echo __METHOD__, PHP_EOL; }
+ static function continue(){ echo __METHOD__, PHP_EOL; }
+ static function switch(){ echo __METHOD__, PHP_EOL; }
+ static function yield(){ echo __METHOD__, PHP_EOL; }
+ static function function(){ echo __METHOD__, PHP_EOL; }
+ static function if(){ echo __METHOD__, PHP_EOL; }
+ static function endswitch(){ echo __METHOD__, PHP_EOL; }
+ static function finally(){ echo __METHOD__, PHP_EOL; }
+ static function for(){ echo __METHOD__, PHP_EOL; }
+ static function foreach(){ echo __METHOD__, PHP_EOL; }
+ static function declare(){ echo __METHOD__, PHP_EOL; }
+ static function case(){ echo __METHOD__, PHP_EOL; }
+ static function do(){ echo __METHOD__, PHP_EOL; }
+ static function while(){ echo __METHOD__, PHP_EOL; }
+ static function as(){ echo __METHOD__, PHP_EOL; }
+ static function catch(){ echo __METHOD__, PHP_EOL; }
+ static function die(){ echo __METHOD__, PHP_EOL; }
+ static function self(){ echo __METHOD__, PHP_EOL; }
+ static function parent(){ echo __METHOD__, PHP_EOL; }
+ static function public(){ echo __METHOD__, PHP_EOL; }
+ static function protected(){ echo __METHOD__, PHP_EOL; }
+ static function private(){ echo __METHOD__, PHP_EOL; }
+ static function static(){ echo __METHOD__, PHP_EOL; }
+ static function abstract(){ echo __METHOD__, PHP_EOL; }
+ static function final(){ echo __METHOD__, PHP_EOL; }
+ static function class(){ echo __METHOD__, PHP_EOL; }
+}
+
+Obj::empty();
+Obj::callable();
+Obj::trait();
+Obj::extends();
+Obj::implements();
+Obj::const();
+Obj::enddeclare();
+Obj::endfor();
+Obj::endforeach();
+Obj::endif();
+Obj::endwhile();
+Obj::and();
+Obj::global();
+Obj::goto();
+Obj::instanceof();
+Obj::insteadof();
+Obj::interface();
+Obj::new();
+Obj::or();
+Obj::xor();
+Obj::try();
+Obj::use();
+Obj::var();
+Obj::exit();
+Obj::list();
+Obj::clone();
+Obj::include();
+Obj::include_once();
+Obj::throw();
+Obj::array();
+Obj::print();
+Obj::echo();
+Obj::require();
+Obj::require_once();
+Obj::return();
+Obj::else();
+Obj::elseif();
+Obj::default();
+Obj::break();
+Obj::continue();
+Obj::switch();
+Obj::yield();
+Obj::function();
+Obj::if();
+Obj::endswitch();
+Obj::finally();
+Obj::for();
+Obj::foreach();
+Obj::declare();
+Obj::case();
+Obj::do();
+Obj::while();
+Obj::as();
+Obj::catch();
+Obj::die();
+Obj::self();
+Obj::parent();
+Obj::public();
+Obj::protected();
+Obj::private();
+Obj::static();
+Obj::abstract();
+Obj::final();
+Obj::class();
+
+echo "\nDone\n";
+
+--EXPECTF--
+Obj::empty
+Obj::callable
+Obj::trait
+Obj::extends
+Obj::implements
+Obj::const
+Obj::enddeclare
+Obj::endfor
+Obj::endforeach
+Obj::endif
+Obj::endwhile
+Obj::and
+Obj::global
+Obj::goto
+Obj::instanceof
+Obj::insteadof
+Obj::interface
+Obj::new
+Obj::or
+Obj::xor
+Obj::try
+Obj::use
+Obj::var
+Obj::exit
+Obj::list
+Obj::clone
+Obj::include
+Obj::include_once
+Obj::throw
+Obj::array
+Obj::print
+Obj::echo
+Obj::require
+Obj::require_once
+Obj::return
+Obj::else
+Obj::elseif
+Obj::default
+Obj::break
+Obj::continue
+Obj::switch
+Obj::yield
+Obj::function
+Obj::if
+Obj::endswitch
+Obj::finally
+Obj::for
+Obj::foreach
+Obj::declare
+Obj::case
+Obj::do
+Obj::while
+Obj::as
+Obj::catch
+Obj::die
+Obj::self
+Obj::parent
+Obj::public
+Obj::protected
+Obj::private
+Obj::static
+Obj::abstract
+Obj::final
+Obj::class
+
+Done
diff --git a/Zend/tests/grammar/semi_reserved_003.phpt b/Zend/tests/grammar/semi_reserved_003.phpt
new file mode 100644
index 0000000000..fe2c44dc4c
--- /dev/null
+++ b/Zend/tests/grammar/semi_reserved_003.phpt
@@ -0,0 +1,210 @@
+--TEST--
+Test semi-reserved words as class properties
+--FILE--
+<?php
+
+class Obj
+{
+ var $empty = 'empty';
+ var $callable = 'callable';
+ var $class = 'class';
+ var $trait = 'trait';
+ var $extends = 'extends';
+ var $implements = 'implements';
+ var $static = 'static';
+ var $abstract = 'abstract';
+ var $final = 'final';
+ var $public = 'public';
+ var $protected = 'protected';
+ var $private = 'private';
+ var $const = 'const';
+ var $enddeclare = 'enddeclare';
+ var $endfor = 'endfor';
+ var $endforeach = 'endforeach';
+ var $endif = 'endif';
+ var $endwhile = 'endwhile';
+ var $and = 'and';
+ var $global = 'global';
+ var $goto = 'goto';
+ var $instanceof = 'instanceof';
+ var $insteadof = 'insteadof';
+ var $interface = 'interface';
+ var $namespace = 'namespace';
+ var $new = 'new';
+ var $or = 'or';
+ var $xor = 'xor';
+ var $try = 'try';
+ var $use = 'use';
+ var $var = 'var';
+ var $exit = 'exit';
+ var $list = 'list';
+ var $clone = 'clone';
+ var $include = 'include';
+ var $include_once = 'include_once';
+ var $throw = 'throw';
+ var $array = 'array';
+ var $print = 'print';
+ var $echo = 'echo';
+ var $require = 'require';
+ var $require_once = 'require_once';
+ var $return = 'return';
+ var $else = 'else';
+ var $elseif = 'elseif';
+ var $default = 'default';
+ var $break = 'break';
+ var $continue = 'continue';
+ var $switch = 'switch';
+ var $yield = 'yield';
+ var $function = 'function';
+ var $if = 'if';
+ var $endswitch = 'endswitch';
+ var $finally = 'finally';
+ var $for = 'for';
+ var $foreach = 'foreach';
+ var $declare = 'declare';
+ var $case = 'case';
+ var $do = 'do';
+ var $while = 'while';
+ var $as = 'as';
+ var $catch = 'catch';
+ var $die = 'die';
+ var $self = 'self';
+}
+
+$obj = new Obj;
+
+echo $obj->empty, PHP_EOL;
+echo $obj->callable, PHP_EOL;
+echo $obj->class, PHP_EOL;
+echo $obj->trait, PHP_EOL;
+echo $obj->extends, PHP_EOL;
+echo $obj->implements, PHP_EOL;
+echo $obj->static, PHP_EOL;
+echo $obj->abstract, PHP_EOL;
+echo $obj->final, PHP_EOL;
+echo $obj->public, PHP_EOL;
+echo $obj->protected, PHP_EOL;
+echo $obj->private, PHP_EOL;
+echo $obj->const, PHP_EOL;
+echo $obj->enddeclare, PHP_EOL;
+echo $obj->endfor, PHP_EOL;
+echo $obj->endforeach, PHP_EOL;
+echo $obj->endif, PHP_EOL;
+echo $obj->endwhile, PHP_EOL;
+echo $obj->and, PHP_EOL;
+echo $obj->global, PHP_EOL;
+echo $obj->goto, PHP_EOL;
+echo $obj->instanceof, PHP_EOL;
+echo $obj->insteadof, PHP_EOL;
+echo $obj->interface, PHP_EOL;
+echo $obj->namespace, PHP_EOL;
+echo $obj->new, PHP_EOL;
+echo $obj->or, PHP_EOL;
+echo $obj->xor, PHP_EOL;
+echo $obj->try, PHP_EOL;
+echo $obj->use, PHP_EOL;
+echo $obj->var, PHP_EOL;
+echo $obj->exit, PHP_EOL;
+echo $obj->list, PHP_EOL;
+echo $obj->clone, PHP_EOL;
+echo $obj->include, PHP_EOL;
+echo $obj->include_once, PHP_EOL;
+echo $obj->throw, PHP_EOL;
+echo $obj->array, PHP_EOL;
+echo $obj->print, PHP_EOL;
+echo $obj->echo, PHP_EOL;
+echo $obj->require, PHP_EOL;
+echo $obj->require_once, PHP_EOL;
+echo $obj->return, PHP_EOL;
+echo $obj->else, PHP_EOL;
+echo $obj->elseif, PHP_EOL;
+echo $obj->default, PHP_EOL;
+echo $obj->break, PHP_EOL;
+echo $obj->continue, PHP_EOL;
+echo $obj->switch, PHP_EOL;
+echo $obj->yield, PHP_EOL;
+echo $obj->function, PHP_EOL;
+echo $obj->if, PHP_EOL;
+echo $obj->endswitch, PHP_EOL;
+echo $obj->finally, PHP_EOL;
+echo $obj->for, PHP_EOL;
+echo $obj->foreach, PHP_EOL;
+echo $obj->declare, PHP_EOL;
+echo $obj->case, PHP_EOL;
+echo $obj->do, PHP_EOL;
+echo $obj->while, PHP_EOL;
+echo $obj->as, PHP_EOL;
+echo $obj->catch, PHP_EOL;
+echo $obj->die, PHP_EOL;
+echo $obj->self, PHP_EOL;
+
+echo "\nDone\n";
+
+?>
+--EXPECTF--
+empty
+callable
+class
+trait
+extends
+implements
+static
+abstract
+final
+public
+protected
+private
+const
+enddeclare
+endfor
+endforeach
+endif
+endwhile
+and
+global
+goto
+instanceof
+insteadof
+interface
+namespace
+new
+or
+xor
+try
+use
+var
+exit
+list
+clone
+include
+include_once
+throw
+array
+print
+echo
+require
+require_once
+return
+else
+elseif
+default
+break
+continue
+switch
+yield
+function
+if
+endswitch
+finally
+for
+foreach
+declare
+case
+do
+while
+as
+catch
+die
+self
+
+Done
diff --git a/Zend/tests/grammar/semi_reserved_004.phpt b/Zend/tests/grammar/semi_reserved_004.phpt
new file mode 100644
index 0000000000..40c5df14ef
--- /dev/null
+++ b/Zend/tests/grammar/semi_reserved_004.phpt
@@ -0,0 +1,210 @@
+--TEST--
+Test semi-reserved words as static class properties
+--FILE--
+<?php
+
+class Obj
+{
+ static $empty = 'empty';
+ static $callable = 'callable';
+ static $class = 'class';
+ static $trait = 'trait';
+ static $extends = 'extends';
+ static $implements = 'implements';
+ static $static = 'static';
+ static $abstract = 'abstract';
+ static $final = 'final';
+ static $public = 'public';
+ static $protected = 'protected';
+ static $private = 'private';
+ static $const = 'const';
+ static $enddeclare = 'enddeclare';
+ static $endfor = 'endfor';
+ static $endforeach = 'endforeach';
+ static $endif = 'endif';
+ static $endwhile = 'endwhile';
+ static $and = 'and';
+ static $global = 'global';
+ static $goto = 'goto';
+ static $instanceof = 'instanceof';
+ static $insteadof = 'insteadof';
+ static $interface = 'interface';
+ static $namespace = 'namespace';
+ static $new = 'new';
+ static $or = 'or';
+ static $xor = 'xor';
+ static $try = 'try';
+ static $use = 'use';
+ static $var = 'var';
+ static $exit = 'exit';
+ static $list = 'list';
+ static $clone = 'clone';
+ static $include = 'include';
+ static $include_once = 'include_once';
+ static $throw = 'throw';
+ static $array = 'array';
+ static $print = 'print';
+ static $echo = 'echo';
+ static $require = 'require';
+ static $require_once = 'require_once';
+ static $return = 'return';
+ static $else = 'else';
+ static $elseif = 'elseif';
+ static $default = 'default';
+ static $break = 'break';
+ static $continue = 'continue';
+ static $switch = 'switch';
+ static $yield = 'yield';
+ static $function = 'function';
+ static $if = 'if';
+ static $endswitch = 'endswitch';
+ static $finally = 'finally';
+ static $for = 'for';
+ static $foreach = 'foreach';
+ static $declare = 'declare';
+ static $case = 'case';
+ static $do = 'do';
+ static $while = 'while';
+ static $as = 'as';
+ static $catch = 'catch';
+ static $die = 'die';
+ static $self = 'self';
+ static $parent = 'parent';
+}
+
+echo Obj::$empty, PHP_EOL;
+echo Obj::$callable, PHP_EOL;
+echo Obj::$class, PHP_EOL;
+echo Obj::$trait, PHP_EOL;
+echo Obj::$extends, PHP_EOL;
+echo Obj::$implements, PHP_EOL;
+echo Obj::$static, PHP_EOL;
+echo Obj::$abstract, PHP_EOL;
+echo Obj::$final, PHP_EOL;
+echo Obj::$public, PHP_EOL;
+echo Obj::$protected, PHP_EOL;
+echo Obj::$private, PHP_EOL;
+echo Obj::$const, PHP_EOL;
+echo Obj::$enddeclare, PHP_EOL;
+echo Obj::$endfor, PHP_EOL;
+echo Obj::$endforeach, PHP_EOL;
+echo Obj::$endif, PHP_EOL;
+echo Obj::$endwhile, PHP_EOL;
+echo Obj::$and, PHP_EOL;
+echo Obj::$global, PHP_EOL;
+echo Obj::$goto, PHP_EOL;
+echo Obj::$instanceof, PHP_EOL;
+echo Obj::$insteadof, PHP_EOL;
+echo Obj::$interface, PHP_EOL;
+echo Obj::$namespace, PHP_EOL;
+echo Obj::$new, PHP_EOL;
+echo Obj::$or, PHP_EOL;
+echo Obj::$xor, PHP_EOL;
+echo Obj::$try, PHP_EOL;
+echo Obj::$use, PHP_EOL;
+echo Obj::$var, PHP_EOL;
+echo Obj::$exit, PHP_EOL;
+echo Obj::$list, PHP_EOL;
+echo Obj::$clone, PHP_EOL;
+echo Obj::$include, PHP_EOL;
+echo Obj::$include_once, PHP_EOL;
+echo Obj::$throw, PHP_EOL;
+echo Obj::$array, PHP_EOL;
+echo Obj::$print, PHP_EOL;
+echo Obj::$echo, PHP_EOL;
+echo Obj::$require, PHP_EOL;
+echo Obj::$require_once, PHP_EOL;
+echo Obj::$return, PHP_EOL;
+echo Obj::$else, PHP_EOL;
+echo Obj::$elseif, PHP_EOL;
+echo Obj::$default, PHP_EOL;
+echo Obj::$break, PHP_EOL;
+echo Obj::$continue, PHP_EOL;
+echo Obj::$switch, PHP_EOL;
+echo Obj::$yield, PHP_EOL;
+echo Obj::$function, PHP_EOL;
+echo Obj::$if, PHP_EOL;
+echo Obj::$endswitch, PHP_EOL;
+echo Obj::$finally, PHP_EOL;
+echo Obj::$for, PHP_EOL;
+echo Obj::$foreach, PHP_EOL;
+echo Obj::$declare, PHP_EOL;
+echo Obj::$case, PHP_EOL;
+echo Obj::$do, PHP_EOL;
+echo Obj::$while, PHP_EOL;
+echo Obj::$as, PHP_EOL;
+echo Obj::$catch, PHP_EOL;
+echo Obj::$die, PHP_EOL;
+echo Obj::$self, PHP_EOL;
+echo Obj::$parent, PHP_EOL;
+
+echo "\nDone\n";
+
+--EXPECTF--
+empty
+callable
+class
+trait
+extends
+implements
+static
+abstract
+final
+public
+protected
+private
+const
+enddeclare
+endfor
+endforeach
+endif
+endwhile
+and
+global
+goto
+instanceof
+insteadof
+interface
+namespace
+new
+or
+xor
+try
+use
+var
+exit
+list
+clone
+include
+include_once
+throw
+array
+print
+echo
+require
+require_once
+return
+else
+elseif
+default
+break
+continue
+switch
+yield
+function
+if
+endswitch
+finally
+for
+foreach
+declare
+case
+do
+while
+as
+catch
+die
+self
+parent
+
+Done
diff --git a/Zend/tests/grammar/semi_reserved_005.phpt b/Zend/tests/grammar/semi_reserved_005.phpt
new file mode 100644
index 0000000000..3ad0830b09
--- /dev/null
+++ b/Zend/tests/grammar/semi_reserved_005.phpt
@@ -0,0 +1,207 @@
+--TEST--
+Test semi-reserved words as class constants
+--FILE--
+<?php
+
+class Obj
+{
+ const EMPTY = 'empty';
+ const CALLABLE = 'callable';
+ const TRAIT = 'trait';
+ const EXTENDS = 'extends';
+ const IMPLEMENTS = 'implements';
+ const CONST = 'const';
+ const ENDDECLARE = 'enddeclare';
+ const ENDFOR = 'endfor';
+ const ENDFOREACH = 'endforeach';
+ const ENDIF = 'endif';
+ const ENDWHILE = 'endwhile';
+ const AND = 'and';
+ const GLOBAL = 'global';
+ const GOTO = 'goto';
+ const INSTANCEOF = 'instanceof';
+ const INSTEADOF = 'insteadof';
+ const INTERFACE = 'interface';
+ const NAMESPACE = 'namespace';
+ const NEW = 'new';
+ const OR = 'or';
+ const XOR = 'xor';
+ const TRY = 'try';
+ const USE = 'use';
+ const VAR = 'var';
+ const EXIT = 'exit';
+ const LIST = 'list';
+ const CLONE = 'clone';
+ const INCLUDE = 'include';
+ const INCLUDE_ONCE = 'include_once';
+ const THROW = 'throw';
+ const ARRAY = 'array';
+ const PRINT = 'print';
+ const ECHO = 'echo';
+ const REQUIRE = 'require';
+ const REQUIRE_ONCE = 'require_once';
+ const RETURN = 'return';
+ const ELSE = 'else';
+ const ELSEIF = 'elseif';
+ const DEFAULT = 'default';
+ const BREAK = 'break';
+ const CONTINUE = 'continue';
+ const SWITCH = 'switch';
+ const YIELD = 'yield';
+ const FUNCTION = 'function';
+ const IF = 'if';
+ const ENDSWITCH = 'endswitch';
+ const FINALLY = 'finally';
+ const FOR = 'for';
+ const FOREACH = 'foreach';
+ const DECLARE = 'declare';
+ const CASE = 'case';
+ const DO = 'do';
+ const WHILE = 'while';
+ const AS = 'as';
+ const CATCH = 'catch';
+ const DIE = 'die';
+ const SELF = 'self';
+ const PARENT = 'parent';
+ const PUBLIC = 'public';
+ const PROTECTED = 'protected';
+ const PRIVATE = 'private';
+ const STATIC = 'static';
+ const ABSTRACT = 'abstract';
+ const FINAL = 'final';
+}
+
+echo Obj::EMPTY, PHP_EOL;
+echo Obj::CALLABLE, PHP_EOL;
+echo Obj::TRAIT, PHP_EOL;
+echo Obj::EXTENDS, PHP_EOL;
+echo Obj::IMPLEMENTS, PHP_EOL;
+echo Obj::CONST, PHP_EOL;
+echo Obj::ENDDECLARE, PHP_EOL;
+echo Obj::ENDFOR, PHP_EOL;
+echo Obj::ENDFOREACH, PHP_EOL;
+echo Obj::ENDIF, PHP_EOL;
+echo Obj::ENDWHILE, PHP_EOL;
+echo Obj::AND, PHP_EOL;
+echo Obj::GLOBAL, PHP_EOL;
+echo Obj::GOTO, PHP_EOL;
+echo Obj::INSTANCEOF, PHP_EOL;
+echo Obj::INSTEADOF, PHP_EOL;
+echo Obj::INTERFACE, PHP_EOL;
+echo Obj::NAMESPACE, PHP_EOL;
+echo Obj::NEW, PHP_EOL;
+echo Obj::OR, PHP_EOL;
+echo Obj::XOR, PHP_EOL;
+echo Obj::TRY, PHP_EOL;
+echo Obj::USE, PHP_EOL;
+echo Obj::VAR, PHP_EOL;
+echo Obj::EXIT, PHP_EOL;
+echo Obj::LIST, PHP_EOL;
+echo Obj::CLONE, PHP_EOL;
+echo Obj::INCLUDE, PHP_EOL;
+echo Obj::INCLUDE_ONCE, PHP_EOL;
+echo Obj::THROW, PHP_EOL;
+echo Obj::ARRAY, PHP_EOL;
+echo Obj::PRINT, PHP_EOL;
+echo Obj::ECHO, PHP_EOL;
+echo Obj::REQUIRE, PHP_EOL;
+echo Obj::REQUIRE_ONCE, PHP_EOL;
+echo Obj::RETURN, PHP_EOL;
+echo Obj::ELSE, PHP_EOL;
+echo Obj::ELSEIF, PHP_EOL;
+echo Obj::DEFAULT, PHP_EOL;
+echo Obj::BREAK, PHP_EOL;
+echo Obj::CONTINUE, PHP_EOL;
+echo Obj::SWITCH, PHP_EOL;
+echo Obj::YIELD, PHP_EOL;
+echo Obj::FUNCTION, PHP_EOL;
+echo Obj::IF, PHP_EOL;
+echo Obj::ENDSWITCH, PHP_EOL;
+echo Obj::FINALLY, PHP_EOL;
+echo Obj::FOR, PHP_EOL;
+echo Obj::FOREACH, PHP_EOL;
+echo Obj::DECLARE, PHP_EOL;
+echo Obj::CASE, PHP_EOL;
+echo Obj::DO, PHP_EOL;
+echo Obj::WHILE, PHP_EOL;
+echo Obj::AS, PHP_EOL;
+echo Obj::CATCH, PHP_EOL;
+echo Obj::DIE, PHP_EOL;
+echo Obj::SELF, PHP_EOL;
+echo Obj::PARENT, PHP_EOL;
+echo Obj::PUBLIC, PHP_EOL;
+echo Obj::PROTECTED, PHP_EOL;
+echo Obj::PRIVATE, PHP_EOL;
+echo Obj::STATIC, PHP_EOL;
+echo Obj::ABSTRACT, PHP_EOL;
+echo Obj::FINAL, PHP_EOL;
+
+echo "\nDone\n";
+
+--EXPECTF--
+empty
+callable
+trait
+extends
+implements
+const
+enddeclare
+endfor
+endforeach
+endif
+endwhile
+and
+global
+goto
+instanceof
+insteadof
+interface
+namespace
+new
+or
+xor
+try
+use
+var
+exit
+list
+clone
+include
+include_once
+throw
+array
+print
+echo
+require
+require_once
+return
+else
+elseif
+default
+break
+continue
+switch
+yield
+function
+if
+endswitch
+finally
+for
+foreach
+declare
+case
+do
+while
+as
+catch
+die
+self
+parent
+public
+protected
+private
+static
+abstract
+final
+
+Done
diff --git a/Zend/tests/grammar/semi_reserved_006.phpt b/Zend/tests/grammar/semi_reserved_006.phpt
new file mode 100644
index 0000000000..334d09ac36
--- /dev/null
+++ b/Zend/tests/grammar/semi_reserved_006.phpt
@@ -0,0 +1,80 @@
+--TEST--
+Test semi-reserved method and constant names and trait conflict resolution
+--FILE--
+<?php
+
+trait TraitA
+{
+ public function catch(){ echo __METHOD__, PHP_EOL; }
+ private function list(){ echo __METHOD__, PHP_EOL; }
+}
+
+trait TraitB
+{
+ static $list = ['a' => ['b' => ['c']]];
+
+ public static function catch(){ echo __METHOD__, PHP_EOL; }
+ private static function throw(){ echo __METHOD__, PHP_EOL; }
+ private static function self(){ echo __METHOD__, PHP_EOL; }
+}
+
+trait TraitC
+{
+ public static function exit(){ echo __METHOD__, PHP_EOL; }
+ protected static function try(){ echo __METHOD__, PHP_EOL; }
+}
+
+class Foo
+{
+ use TraitA, TraitB {
+ TraitA
+ ::
+ catch insteadof namespace\TraitB;
+ TraitA::list as public foreach;
+ TraitB::throw as public;
+ TraitB::self as public;
+ }
+
+ use TraitC {
+ try as public attempt;
+ exit as die;
+ \TraitC::exit as bye;
+ namespace\TraitC::exit as byebye;
+ TraitC
+ ::
+ exit as farewell;
+ }
+}
+
+(new Foo)->catch();
+(new Foo)->foreach();
+Foo::throw();
+Foo::self();
+var_dump(Foo::$list['a']);
+Foo::attempt();
+Foo::die();
+Foo::bye();
+Foo::byebye();
+Foo::farewell();
+
+echo "\nDone\n";
+
+--EXPECTF--
+TraitA::catch
+TraitA::list
+TraitB::throw
+TraitB::self
+array(1) {
+ ["b"]=>
+ array(1) {
+ [0]=>
+ string(1) "c"
+ }
+}
+TraitC::try
+TraitC::exit
+TraitC::exit
+TraitC::exit
+TraitC::exit
+
+Done
diff --git a/Zend/tests/grammar/semi_reserved_007.phpt b/Zend/tests/grammar/semi_reserved_007.phpt
new file mode 100644
index 0000000000..5105629cbe
--- /dev/null
+++ b/Zend/tests/grammar/semi_reserved_007.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Edge case: self::self, self::parent, parent::self semi reserved constants access
+--FILE--
+<?php
+
+class Foo {
+ const self = "self";
+ const parent = "parent";
+ public function __construct() {
+ echo "From ", __METHOD__, ":", PHP_EOL;
+ echo self::self, PHP_EOL;
+ echo self::parent, PHP_EOL;
+ }
+}
+
+class Bar extends Foo {
+ public function __construct() {
+ parent::__construct();
+ echo "From ", __METHOD__, ":", PHP_EOL;
+ echo parent::self, PHP_EOL;
+ echo parent::parent, PHP_EOL;
+ }
+}
+
+new Bar;
+
+echo "\nDone\n";
+
+--EXPECTF--
+From Foo::__construct:
+self
+parent
+From Bar::__construct:
+self
+parent
+
+Done \ No newline at end of file
diff --git a/Zend/tests/grammar/semi_reserved_008.phpt b/Zend/tests/grammar/semi_reserved_008.phpt
new file mode 100644
index 0000000000..43218b1b05
--- /dev/null
+++ b/Zend/tests/grammar/semi_reserved_008.phpt
@@ -0,0 +1,68 @@
+--TEST--
+Testing with comments around semi-reserved names (not intended to be legible)
+--FILE--
+<?php
+
+trait TraitA
+{
+ public static function list(){ echo __METHOD__, PHP_EOL; }
+ public static function /* comment */ catch(){ echo __METHOD__, PHP_EOL; }
+ private static function // comment
+ throw(){ echo __METHOD__, PHP_EOL; }
+ private static function
+ # comment
+ self(){ echo __METHOD__, PHP_EOL; }
+}
+
+trait TraitB
+{
+ public static function exit(){ echo __METHOD__, PHP_EOL; }
+ protected static function try(){ echo __METHOD__, PHP_EOL; }
+}
+
+class Foo
+{
+ use TraitA {
+ TraitA::
+ //
+ /** doc comment */
+ #
+ catch /* comment */
+ // comment
+ # comment
+ insteadof TraitB;
+
+ TraitA::list as public /**/ foreach;
+ }
+
+ use TraitB {
+ try /*comment*/ as public attempt;
+ exit // comment
+ as/*comment*/die; // non qualified
+ \TraitB::exit as bye; // full qualified
+ namespace\TraitB::exit #
+ as byebye; // even more full qualified
+ TraitB
+ ::
+ /** */
+ exit as farewell; // full qualified with weird spacing
+ }
+}
+
+Foo /**/
+#
+//
+/** */
+::
+/**/
+#
+//
+/** */
+attempt();
+
+echo PHP_EOL, "Done", PHP_EOL;
+
+--EXPECTF--
+TraitB::try
+
+Done
diff --git a/Zend/tests/grammar/semi_reserved_009.phpt b/Zend/tests/grammar/semi_reserved_009.phpt
new file mode 100644
index 0000000000..1a7b0fc371
--- /dev/null
+++ b/Zend/tests/grammar/semi_reserved_009.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Edge case: T_STRING<as> as T_STRING<?>
+--FILE--
+<?php
+
+trait TraitA
+{
+ public static function as(){ echo __METHOD__, PHP_EOL; }
+}
+
+class Foo
+{
+ use TraitA {
+ as as try;
+ }
+}
+
+Foo::try();
+
+echo PHP_EOL, "Done", PHP_EOL;
+
+--EXPECTF--
+TraitA::as
+
+Done
diff --git a/Zend/tests/grammar/semi_reserved_010.phpt b/Zend/tests/grammar/semi_reserved_010.phpt
new file mode 100644
index 0000000000..508a7867a4
--- /dev/null
+++ b/Zend/tests/grammar/semi_reserved_010.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Edge case: T_STRING<insteadof> insteadof T_STRING<?>
+--FILE--
+<?php
+
+trait TraitA
+{
+ public static function insteadof(){ echo __METHOD__, PHP_EOL; }
+}
+
+trait TraitB
+{
+ public static function insteadof(){ echo __METHOD__, PHP_EOL; }
+}
+
+class Foo
+{
+ use TraitA , TraitB {
+ TraitB::insteadof
+ insteadof TraitA;
+ }
+}
+
+Foo::insteadof();
+
+echo PHP_EOL, "Done", PHP_EOL;
+
+--EXPECTF--
+TraitB::insteadof
+
+Done
diff --git a/Zend/tests/loop_free_on_return.phpt b/Zend/tests/loop_free_on_return.phpt
new file mode 100644
index 0000000000..525a50955a
--- /dev/null
+++ b/Zend/tests/loop_free_on_return.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Break out of while loop that is followed by a return statement and inside a foreach loop
+--FILE--
+<?php
+
+$a = [42];
+foreach ($a as $b) {
+ while (1) {
+ break 2;
+ }
+ return;
+}
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/Zend/tests/ns_071.phpt b/Zend/tests/ns_071.phpt
index 53ff7f018a..2f2fcfad1a 100644
--- a/Zend/tests/ns_071.phpt
+++ b/Zend/tests/ns_071.phpt
@@ -20,6 +20,6 @@ NULL
Fatal error: Uncaught TypeError: Argument 1 passed to foo\bar::__construct() must be of the type array, object given, called in %s on line %d and defined in %s:%d
Stack trace:
-#0 %s(%d): foo\bar->__construct()
+#0 %s(%d): foo\bar->__construct(Object(stdClass))
#1 {main}
thrown in %s on line %d
diff --git a/Zend/tests/ns_072.phpt b/Zend/tests/ns_072.phpt
index 877095df4a..6375682890 100644
--- a/Zend/tests/ns_072.phpt
+++ b/Zend/tests/ns_072.phpt
@@ -32,6 +32,6 @@ NULL
Fatal error: Uncaught TypeError: Argument 1 passed to foo\bar::__construct() must implement interface foo\foo, instance of stdClass given, called in %s on line %d and defined in %s:%d
Stack trace:
-#0 %s(%d): foo\bar->__construct()
+#0 %s(%d): foo\bar->__construct(Object(stdClass))
#1 {main}
thrown in %s on line %d
diff --git a/Zend/tests/objects_022.phpt b/Zend/tests/objects_022.phpt
index 913de7d990..01f961bae1 100644
--- a/Zend/tests/objects_022.phpt
+++ b/Zend/tests/objects_022.phpt
@@ -38,6 +38,6 @@ object(baz)#%d (0) {
Fatal error: Uncaught TypeError: Argument 1 passed to foo::testFoo() must be an instance of foo, instance of stdClass given, called in %s on line %d and defined in %s:%d
Stack trace:
-#0 %s(%d): foo->testFoo()
+#0 %s(%d): foo->testFoo(Object(stdClass))
#1 {main}
thrown in %s on line %d
diff --git a/Zend/tests/return_types/028.phpt b/Zend/tests/return_types/028.phpt
new file mode 100644
index 0000000000..d2a78ede4a
--- /dev/null
+++ b/Zend/tests/return_types/028.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Memory leak when returning TMP/VAR with wrong return type
+--FILE--
+<?php
+
+function foo(): stdClass {
+ $a = new stdClass;
+ $b = [];
+ return [$a, $b];
+}
+
+try {
+ foo();
+} catch (Error $e) {
+ print $e->getMessage();
+}
+
+?>
+--EXPECTF--
+Return value of foo() must be an instance of stdClass, array returned in %s on line %d
diff --git a/Zend/tests/typehints/explicit_weak_include_strict.phpt b/Zend/tests/typehints/explicit_weak_include_strict.phpt
index 1593c70950..fb53d8ce11 100644
--- a/Zend/tests/typehints/explicit_weak_include_strict.phpt
+++ b/Zend/tests/typehints/explicit_weak_include_strict.phpt
@@ -13,7 +13,7 @@ require 'weak_include_strict_2.inc';
--EXPECTF--
Fatal error: Uncaught TypeError: Argument 1 passed to takes_int() must be of the type integer, float given, called in %sweak_include_strict_2.inc on line 9 and defined in %sweak_include_strict_2.inc:5
Stack trace:
-#0 %s(%d): takes_int()
+#0 %s(%d): takes_int(1)
#1 %s(%d): require('%s')
#2 {main}
thrown in %sweak_include_strict_2.inc on line 5
diff --git a/Zend/tests/typehints/strict_call_weak.phpt b/Zend/tests/typehints/strict_call_weak.phpt
index 8ebed2216b..e3a606ec12 100644
--- a/Zend/tests/typehints/strict_call_weak.phpt
+++ b/Zend/tests/typehints/strict_call_weak.phpt
@@ -15,7 +15,7 @@ function_declared_in_weak_mode(1.0);
--EXPECTF--
Fatal error: Uncaught TypeError: Argument 1 passed to function_declared_in_weak_mode() must be of the type integer, float given, called in %sstrict_call_weak.php on line 10 and defined in %sstrict_call_weak_2.inc:5
Stack trace:
-#0 %s(%d): function_declared_in_weak_mode()
+#0 %s(%d): function_declared_in_weak_mode(1)
#1 {main}
thrown in %sstrict_call_weak_2.inc on line 5
diff --git a/Zend/tests/typehints/strict_call_weak_explicit.phpt b/Zend/tests/typehints/strict_call_weak_explicit.phpt
index 215a0b1fcb..22c5b4319c 100644
--- a/Zend/tests/typehints/strict_call_weak_explicit.phpt
+++ b/Zend/tests/typehints/strict_call_weak_explicit.phpt
@@ -15,7 +15,7 @@ function_declared_in_weak_mode(1.0);
--EXPECTF--
Fatal error: Uncaught TypeError: Argument 1 passed to function_declared_in_weak_mode() must be of the type integer, float given, called in %sstrict_call_weak_explicit.php on line 10 and defined in %sstrict_call_weak_explicit_2.inc:5
Stack trace:
-#0 %s(%d): function_declared_in_weak_mode()
+#0 %s(%d): function_declared_in_weak_mode(1)
#1 {main}
thrown in %sstrict_call_weak_explicit_2.inc on line 5
diff --git a/Zend/tests/typehints/weak_include_strict.phpt b/Zend/tests/typehints/weak_include_strict.phpt
index 5cd1895d66..e49485dbe5 100644
--- a/Zend/tests/typehints/weak_include_strict.phpt
+++ b/Zend/tests/typehints/weak_include_strict.phpt
@@ -13,7 +13,7 @@ require 'weak_include_strict_2.inc';
--EXPECTF--
Fatal error: Uncaught TypeError: Argument 1 passed to takes_int() must be of the type integer, float given, called in %sweak_include_strict_2.inc on line 9 and defined in %sweak_include_strict_2.inc:5
Stack trace:
-#0 %s(%d): takes_int()
+#0 %s(%d): takes_int(1)
#1 %s(%d): require('%s')
#2 {main}
thrown in %sweak_include_strict_2.inc on line 5
diff --git a/Zend/tests/variadic/closure_invoke.phpt b/Zend/tests/variadic/closure_invoke.phpt
new file mode 100644
index 0000000000..6641ff8fb0
--- /dev/null
+++ b/Zend/tests/variadic/closure_invoke.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Closure::__invoke() with variadic parameter
+--FILE--
+<?php
+
+$closure = function(&...$refs) {};
+$closure->__invoke(
+ $v1, $v2, $v3, $v4,
+ $v5, $v6, $v7, $v8,
+ $v9, $v10, $v11, $v12,
+ $v13
+);
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/Zend/tests/variadic/typehint_error.phpt b/Zend/tests/variadic/typehint_error.phpt
index 9f9a97bc56..26842bbcc2 100644
--- a/Zend/tests/variadic/typehint_error.phpt
+++ b/Zend/tests/variadic/typehint_error.phpt
@@ -35,6 +35,6 @@ array(3) {
Fatal error: Uncaught TypeError: Argument 3 passed to test() must be of the type array, integer given, called in %s:%d
Stack trace:
-#0 %s(%d): test(Array, Array)
+#0 %s(%d): test(Array, Array, 2)
#1 {main}
thrown in %s on line %d
diff --git a/Zend/zend.c b/Zend/zend.c
index 1c2cfd6c77..7fd6f7fc7b 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -727,6 +727,9 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
ini_scanner_globals_ctor(&ini_scanner_globals);
php_scanner_globals_ctor(&language_scanner_globals);
zend_set_default_compile_time_values();
+#ifdef ZEND_WIN32
+ zend_get_windows_version_info(&EG(windows_version_info));
+#endif
#endif
EG(error_reporting) = E_ALL & ~E_NOTICE;
@@ -798,9 +801,6 @@ void zend_post_startup(void) /* {{{ */
global_persistent_list = &EG(persistent_list);
zend_copy_ini_directives();
#else
-#ifdef ZEND_WIN32
- zend_get_windows_version_info(&EG(windows_version_info));
-#endif
virtual_cwd_deactivate();
#endif
}
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 7f8587ab4f..f49957a7ff 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -476,7 +476,7 @@ ZEND_API int ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest
zval_dtor(arg);
ZVAL_NULL(arg);
if (!zend_make_printable_zval(z, arg)) {
- ZVAL_ZVAL(arg, z, 1, 1);
+ ZVAL_COPY_VALUE(arg, z);
}
*dest = Z_STR_P(arg);
return 1;
@@ -1118,104 +1118,84 @@ ZEND_API void zend_merge_properties(zval *obj, HashTable *properties) /* {{{ */
}
/* }}} */
-static int zval_update_class_constant(zval *pp, int is_static, uint32_t offset) /* {{{ */
-{
- ZVAL_DEREF(pp);
- if (Z_CONSTANT_P(pp)) {
- zend_class_entry **scope = EG(current_execute_data) ? &EG(scope) : &CG(active_class_entry);
-
- if ((*scope)->parent) {
- zend_class_entry *ce = *scope;
- zend_property_info *prop_info;
-
- do {
- ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
- if (is_static == ((prop_info->flags & ZEND_ACC_STATIC) != 0) &&
- offset == prop_info->offset) {
- int ret;
- zend_class_entry *old_scope = *scope;
- *scope = prop_info->ce;
- ret = zval_update_constant_ex(pp, 1, NULL);
- *scope = old_scope;
- return ret;
- }
- } ZEND_HASH_FOREACH_END();
- ce = ce->parent;
- } while (ce);
-
- }
- return zval_update_constant_ex(pp, 1, NULL);
- }
- return SUCCESS;
-}
-/* }}} */
-
ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */
{
- int i;
-
- /* initialize static members of internal class */
- if (!CE_STATIC_MEMBERS(class_type) && class_type->default_static_members_count) {
- zval *p;
+ if (!(class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
+ class_type->ce_flags |= ZEND_ACC_CONSTANTS_UPDATED;
if (class_type->parent) {
if (UNEXPECTED(zend_update_class_constants(class_type->parent) != SUCCESS)) {
return FAILURE;
}
}
+
+ if (!CE_STATIC_MEMBERS(class_type) && class_type->default_static_members_count) {
+ /* initialize static members of internal class */
+ int i;
+ zval *p;
+
#if ZTS
- CG(static_members_table)[(zend_intptr_t)(class_type->static_members_table)] = emalloc(sizeof(zval) * class_type->default_static_members_count);
+ CG(static_members_table)[(zend_intptr_t)(class_type->static_members_table)] = emalloc(sizeof(zval) * class_type->default_static_members_count);
#else
- class_type->static_members_table = emalloc(sizeof(zval) * class_type->default_static_members_count);
+ class_type->static_members_table = emalloc(sizeof(zval) * class_type->default_static_members_count);
#endif
- for (i = 0; i < class_type->default_static_members_count; i++) {
- p = &class_type->default_static_members_table[i];
- if (Z_ISREF_P(p) &&
- class_type->parent &&
- i < class_type->parent->default_static_members_count &&
- p == &class_type->parent->default_static_members_table[i] &&
- Z_TYPE(CE_STATIC_MEMBERS(class_type->parent)[i]) != IS_UNDEF
- ) {
- zval *q = &CE_STATIC_MEMBERS(class_type->parent)[i];
-
- ZVAL_NEW_REF(q, q);
- ZVAL_COPY_VALUE(&CE_STATIC_MEMBERS(class_type)[i], q);
- Z_ADDREF_P(q);
- } else {
- ZVAL_DUP(&CE_STATIC_MEMBERS(class_type)[i], p);
- }
- }
- }
-
- if ((class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED) == 0) {
- zend_class_entry **scope = EG(current_execute_data) ? &EG(scope) : &CG(active_class_entry);
- zend_class_entry *old_scope = *scope;
- zval *val;
-
- *scope = class_type;
-
- ZEND_HASH_FOREACH_VAL(&class_type->constants_table, val) {
- if (UNEXPECTED(zval_update_constant_ex(val, 1, class_type) != SUCCESS)) {
- return FAILURE;
+ for (i = 0; i < class_type->default_static_members_count; i++) {
+ p = &class_type->default_static_members_table[i];
+ if (Z_ISREF_P(p) &&
+ class_type->parent &&
+ i < class_type->parent->default_static_members_count &&
+ p == &class_type->parent->default_static_members_table[i] &&
+ Z_TYPE(CE_STATIC_MEMBERS(class_type->parent)[i]) != IS_UNDEF
+ ) {
+ zval *q = &CE_STATIC_MEMBERS(class_type->parent)[i];
+
+ ZVAL_NEW_REF(q, q);
+ ZVAL_COPY_VALUE(&CE_STATIC_MEMBERS(class_type)[i], q);
+ Z_ADDREF_P(q);
+ } else {
+ ZVAL_DUP(&CE_STATIC_MEMBERS(class_type)[i], p);
+ }
}
- } ZEND_HASH_FOREACH_END();
+ } else {
+ zend_class_entry **scope = EG(current_execute_data) ? &EG(scope) : &CG(active_class_entry);
+ zend_class_entry *old_scope = *scope;
+ zend_class_entry *ce;
+ zval *val;
+ zend_property_info *prop_info;
- for (i = 0; i < class_type->default_properties_count; i++) {
- if (Z_TYPE(class_type->default_properties_table[i]) != IS_UNDEF) {
- if (UNEXPECTED(zval_update_class_constant(&class_type->default_properties_table[i], 0, OBJ_PROP_TO_OFFSET(i)) != SUCCESS)) {
- return FAILURE;
+ *scope = class_type;
+ ZEND_HASH_FOREACH_VAL(&class_type->constants_table, val) {
+ ZVAL_DEREF(val);
+ if (Z_CONSTANT_P(val)) {
+ if (UNEXPECTED(zval_update_constant_ex(val, 1, class_type) != SUCCESS)) {
+ return FAILURE;
+ }
}
- }
- }
+ } ZEND_HASH_FOREACH_END();
- for (i = 0; i < class_type->default_static_members_count; i++) {
- if (UNEXPECTED(zval_update_class_constant(&CE_STATIC_MEMBERS(class_type)[i], 1, i) != SUCCESS)) {
- return FAILURE;
+ ce = class_type;
+ while (ce) {
+ ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
+ if (prop_info->ce == ce) {
+ if (prop_info->flags & ZEND_ACC_STATIC) {
+ val = CE_STATIC_MEMBERS(class_type) + prop_info->offset;
+ } else {
+ val = (zval*)((char*)class_type->default_properties_table + prop_info->offset - OBJ_PROP_TO_OFFSET(0));
+ }
+ ZVAL_DEREF(val);
+ if (Z_CONSTANT_P(val)) {
+ *scope = ce;
+ if (UNEXPECTED(zval_update_constant_ex(val, 1, NULL) != SUCCESS)) {
+ return FAILURE;
+ }
+ }
+ }
+ } ZEND_HASH_FOREACH_END();
+ ce = ce->parent;
}
- }
- *scope = old_scope;
- class_type->ce_flags |= ZEND_ACC_CONSTANTS_UPDATED;
+ *scope = old_scope;
+ }
}
return SUCCESS;
}
@@ -1313,10 +1293,12 @@ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type
return FAILURE;
}
- if (UNEXPECTED(zend_update_class_constants(class_type) != SUCCESS)) {
- ZVAL_NULL(arg);
- Z_OBJ_P(arg) = NULL;
- return FAILURE;
+ if (UNEXPECTED(!(class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) {
+ if (UNEXPECTED(zend_update_class_constants(class_type) != SUCCESS)) {
+ ZVAL_NULL(arg);
+ Z_OBJ_P(arg) = NULL;
+ return FAILURE;
+ }
}
if (class_type->create_object == NULL) {
@@ -3632,13 +3614,16 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
if (ce->type == ZEND_INTERNAL_CLASS) {
property_info = pemalloc(sizeof(zend_property_info), 1);
+ if ((access_type & ZEND_ACC_STATIC) || Z_CONSTANT_P(property)) {
+ ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
+ }
} else {
property_info = zend_arena_alloc(&CG(arena), sizeof(zend_property_info));
+ if (Z_CONSTANT_P(property)) {
+ ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
+ }
}
- if (Z_CONSTANT_P(property)) {
- ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
- }
if (!(access_type & ZEND_ACC_PPP_MASK)) {
access_type |= ZEND_ACC_PUBLIC;
}
@@ -3680,18 +3665,13 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
break;
}
}
- switch (access_type & ZEND_ACC_PPP_MASK) {
- case ZEND_ACC_PRIVATE: {
- property_info->name = zend_mangle_property_name(ce->name->val, ce->name->len, name->val, name->len, ce->type & ZEND_INTERNAL_CLASS);
- }
- break;
- case ZEND_ACC_PROTECTED: {
- property_info->name = zend_mangle_property_name("*", 1, name->val, name->len, ce->type & ZEND_INTERNAL_CLASS);
- }
- break;
- case ZEND_ACC_PUBLIC:
- property_info->name = zend_string_copy(name);
- break;
+ if (access_type & ZEND_ACC_PUBLIC) {
+ property_info->name = zend_string_copy(name);
+ } else if (access_type & ZEND_ACC_PRIVATE) {
+ property_info->name = zend_mangle_property_name(ce->name->val, ce->name->len, name->val, name->len, ce->type & ZEND_INTERNAL_CLASS);
+ } else {
+ ZEND_ASSERT(access_type & ZEND_ACC_PROTECTED);
+ property_info->name = zend_mangle_property_name("*", 1, name->val, name->len, ce->type & ZEND_INTERNAL_CLASS);
}
property_info->name = zend_new_interned_string(property_info->name);
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index f61091ae72..83e5265fd4 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -68,9 +68,9 @@ typedef struct _zend_fcall_info_cache {
#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
#define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))
-#define ZEND_FENTRY(zend_name, name, arg_info, flags) { #zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },
+#define ZEND_FENTRY(zend_name, name, arg_info, flags) { #zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags },
-#define ZEND_RAW_FENTRY(zend_name, name, arg_info, flags) { zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },
+#define ZEND_RAW_FENTRY(zend_name, name, arg_info, flags) { zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags },
#define ZEND_RAW_NAMED_FE(zend_name, name, arg_info) ZEND_RAW_FENTRY(#zend_name, name, arg_info, 0)
#define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0)
@@ -593,20 +593,17 @@ END_EXTERN_C()
zval *__z = (z); \
zval *__zv = (zv); \
if (EXPECTED(!Z_ISREF_P(__zv))) { \
- ZVAL_COPY_VALUE(__z, __zv); \
- } else { \
- ZVAL_COPY_VALUE(__z, \
- Z_REFVAL_P(__zv)); \
- } \
- if (copy) { \
- zval_opt_copy_ctor(__z); \
- } \
- if (dtor) { \
- if (!copy) { \
- ZVAL_NULL(__zv); \
+ if (copy && !dtor) { \
+ ZVAL_COPY(__z, __zv); \
+ } else { \
+ ZVAL_COPY_VALUE(__z, __zv); \
+ } \
+ } else { \
+ ZVAL_COPY(__z, Z_REFVAL_P(__zv)); \
+ if (dtor || !copy) { \
+ zval_ptr_dtor(__zv); \
} \
- zval_ptr_dtor(__zv); \
- } \
+ } \
} while (0)
#define RETVAL_BOOL(b) ZVAL_BOOL(return_value, b)
@@ -645,18 +642,6 @@ END_EXTERN_C()
#define RETURN_FALSE { RETVAL_FALSE; return; }
#define RETURN_TRUE { RETVAL_TRUE; return; }
-#define RETVAL_ZVAL_FAST(z) do { \
- zval *_z = (z); \
- if (Z_ISREF_P(_z)) { \
- RETVAL_ZVAL(_z, 1, 0); \
- } else { \
- zval_ptr_dtor(return_value); \
- ZVAL_COPY(return_value, _z); \
- } \
-} while (0)
-
-#define RETURN_ZVAL_FAST(z) { RETVAL_ZVAL_FAST(z); return; }
-
#define HASH_OF(p) (Z_TYPE_P(p)==IS_ARRAY ? Z_ARRVAL_P(p) : ((Z_TYPE_P(p)==IS_OBJECT ? Z_OBJ_HT_P(p)->get_properties((p)) : NULL)))
#define ZVAL_IS_NULL(z) (Z_TYPE_P(z) == IS_NULL)
@@ -774,6 +759,8 @@ ZEND_API void ZEND_FASTCALL zend_wrong_callback_error(int severity, int num, cha
#define Z_PARAM_PROLOGUE(separate) \
++_i; \
+ ZEND_ASSERT(_i <= _min_num_args || _optional==1); \
+ ZEND_ASSERT(_i > _min_num_args || _optional==0); \
if (_optional) { \
if (UNEXPECTED(_i >_num_args)) break; \
} \
@@ -1010,7 +997,10 @@ ZEND_API void ZEND_FASTCALL zend_wrong_callback_error(int severity, int num, cha
Z_PARAM_PROLOGUE(separate); \
zend_parse_arg_zval_deref(_arg, &dest, check_null); \
} else { \
- if (UNEXPECTED(++_i >_num_args)) break; \
+ ++_i; \
+ ZEND_ASSERT(_i <= _min_num_args || _optional==1); \
+ ZEND_ASSERT(_i > _min_num_args || _optional==0); \
+ if (_optional && UNEXPECTED(_i >_num_args)) break; \
_real_arg++; \
zend_parse_arg_zval(_real_arg, &dest, check_null); \
}
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
index 8f88368bc3..2d47b643c3 100644
--- a/Zend/zend_alloc.c
+++ b/Zend/zend_alloc.c
@@ -2048,6 +2048,7 @@ void zend_mm_shutdown(zend_mm_heap *heap, int full, int silent)
#endif
#if ZEND_MM_STAT
heap->real_peak = ZEND_MM_CHUNK_SIZE;
+ heap->size = heap->peak = 0;
#endif
}
}
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c
index 34a2e132f9..fe78bfd31b 100644
--- a/Zend/zend_ast.c
+++ b/Zend/zend_ast.c
@@ -394,7 +394,12 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc
zval tmp;
zend_fetch_dimension_by_zval(&tmp, &op1, &op2);
- ZVAL_ZVAL(result, &tmp, 1, 1);
+ if (UNEXPECTED(Z_ISREF(tmp))) {
+ ZVAL_DUP(result, Z_REFVAL(tmp));
+ } else {
+ ZVAL_DUP(result, &tmp);
+ }
+ zval_ptr_dtor(&tmp);
zval_dtor(&op1);
zval_dtor(&op2);
}
@@ -1149,9 +1154,6 @@ simple_list:
case ZEND_AST_CONST:
zend_ast_export_ns_name(str, ast->child[0], 0, indent);
break;
- case ZEND_AST_RESOLVE_CLASS_NAME:
- zend_ast_export_ns_name(str, ast->child[0], 0, indent);
- APPEND_STR("::class");
case ZEND_AST_UNPACK:
smart_str_appends(str, "...");
ast = ast->child[0];
diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h
index 33aa292fb7..2b8d4d37b8 100644
--- a/Zend/zend_ast.h
+++ b/Zend/zend_ast.h
@@ -66,7 +66,6 @@ enum _zend_ast_kind {
/* 1 child node */
ZEND_AST_VAR = 1 << ZEND_AST_NUM_CHILDREN_SHIFT,
ZEND_AST_CONST,
- ZEND_AST_RESOLVE_CLASS_NAME,
ZEND_AST_UNPACK,
ZEND_AST_UNARY_PLUS,
ZEND_AST_UNARY_MINUS,
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 7313b32065..8989e93fa6 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -459,7 +459,8 @@ ZEND_FUNCTION(func_get_arg)
} else {
arg = ZEND_CALL_ARG(ex, requested_offset + 1);
}
- RETURN_ZVAL_FAST(arg);
+ ZVAL_DEREF(arg);
+ ZVAL_COPY(return_value, arg);
}
/* }}} */
@@ -1105,8 +1106,10 @@ ZEND_FUNCTION(get_class_vars)
RETURN_FALSE;
} else {
array_init(return_value);
- if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
- return;
+ if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) {
+ if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
+ return;
+ }
}
add_class_vars(ce, 0, return_value);
add_class_vars(ce, 1, return_value);
@@ -1684,7 +1687,7 @@ ZEND_FUNCTION(set_error_handler)
}
if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
- RETVAL_ZVAL(&EG(user_error_handler), 1, 0);
+ ZVAL_COPY(return_value, &EG(user_error_handler));
zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting));
zend_stack_push(&EG(user_error_handlers), &EG(user_error_handler));
@@ -1695,7 +1698,7 @@ ZEND_FUNCTION(set_error_handler)
return;
}
- ZVAL_DUP(&EG(user_error_handler), error_handler);
+ ZVAL_COPY(&EG(user_error_handler), error_handler);
EG(user_error_handler_error_reporting) = (int)error_type;
}
/* }}} */
@@ -1752,7 +1755,7 @@ ZEND_FUNCTION(set_exception_handler)
}
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
- RETVAL_ZVAL(&EG(user_exception_handler), 1, 0);
+ ZVAL_COPY(return_value, &EG(user_exception_handler));
zend_stack_push(&EG(user_exception_handlers), &EG(user_exception_handler));
}
@@ -1762,7 +1765,7 @@ ZEND_FUNCTION(set_exception_handler)
return;
}
- ZVAL_DUP(&EG(user_exception_handler), exception_handler);
+ ZVAL_COPY(&EG(user_exception_handler), exception_handler);
}
/* }}} */
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c
index e656f8d6ca..2eeaec639d 100644
--- a/Zend/zend_closures.c
+++ b/Zend/zend_closures.c
@@ -203,6 +203,8 @@ ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *object) /* {
{
zend_closure *closure = (zend_closure *)object;
zend_function *invoke = (zend_function*)emalloc(sizeof(zend_function));
+ const uint32_t keep_flags =
+ ZEND_ACC_RETURN_REFERENCE | ZEND_ACC_VARIADIC | ZEND_ACC_HAS_RETURN_TYPE;
invoke->common = closure->func.common;
/* We return ZEND_INTERNAL_FUNCTION, but arg_info representation is the
@@ -210,7 +212,8 @@ ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *object) /* {
* This is not a problem, because ZEND_ACC_HAS_TYPE_HINTS is never set,
* and we won't check arguments on internal function */
invoke->type = ZEND_INTERNAL_FUNCTION;
- invoke->internal_function.fn_flags = ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER | (closure->func.common.fn_flags & ZEND_ACC_RETURN_REFERENCE);
+ invoke->internal_function.fn_flags =
+ ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER | (closure->func.common.fn_flags & keep_flags);
invoke->internal_function.handler = ZEND_MN(Closure___invoke);
invoke->internal_function.module = 0;
invoke->internal_function.scope = zend_ce_closure;
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 78f8ae3207..bd7b65f1e8 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -102,19 +102,12 @@ static zend_string *zend_build_runtime_definition_key(zend_string *name, unsigne
{
zend_string *result;
char char_pos_buf[32];
- size_t filename_len, char_pos_len = zend_sprintf(char_pos_buf, "%p", lex_pos);
+ size_t char_pos_len = zend_sprintf(char_pos_buf, "%p", lex_pos);
+ zend_string *filename = CG(active_op_array)->filename;
- const char *filename;
- if (CG(active_op_array)->filename) {
- filename = CG(active_op_array)->filename->val;
- filename_len = CG(active_op_array)->filename->len;
- } else {
- filename = "-";
- filename_len = sizeof("-") - 1;
- }
/* NULL, name length, filename length, last accepting char position length */
- result = zend_string_alloc(1 + name->len + filename_len + char_pos_len, 0);
- sprintf(result->val, "%c%s%s%s", '\0', name->val, filename, char_pos_buf);
+ result = zend_string_alloc(1 + name->len + filename->len + char_pos_len, 0);
+ sprintf(result->val, "%c%s%s%s", '\0', name->val, filename->val, char_pos_buf);
return zend_new_interned_string(result);
}
/* }}} */
@@ -179,13 +172,13 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *name) /* {{{ */
}
/* }}} */
-typedef struct _scalar_typehint_info {
+typedef struct _builtin_type_info {
const char* name;
const size_t name_len;
const zend_uchar type;
-} scalar_typehint_info;
+} builtin_type_info;
-static const scalar_typehint_info scalar_typehints[] = {
+static const builtin_type_info builtin_types[] = {
{"int", sizeof("int") - 1, IS_LONG},
{"float", sizeof("float") - 1, IS_DOUBLE},
{"string", sizeof("string") - 1, IS_STRING},
@@ -193,31 +186,20 @@ static const scalar_typehint_info scalar_typehints[] = {
{NULL, 0, IS_UNDEF}
};
-static zend_always_inline const scalar_typehint_info* zend_find_scalar_typehint(const zend_string *name) /* {{{ */
+
+static zend_always_inline zend_uchar zend_lookup_builtin_type_by_name(const zend_string *name) /* {{{ */
{
- const scalar_typehint_info *info = &scalar_typehints[0];
+ const builtin_type_info *info = &builtin_types[0];
for (; info->name; ++info) {
if (name->len == info->name_len
&& zend_binary_strcasecmp(name->val, name->len, info->name, info->name_len) == 0
) {
- return info;
+ return info->type;
}
}
- return NULL;
-}
-/* }}} */
-
-static zend_always_inline zend_uchar zend_lookup_scalar_typehint_by_name(const zend_string *const_name) /* {{{ */
-{
- const scalar_typehint_info *info = zend_find_scalar_typehint(const_name);
-
- if (info) {
- return info->type;
- } else {
- return 0;
- }
+ return 0;
}
/* }}} */
@@ -568,34 +550,44 @@ static int zend_add_const_name_literal(zend_op_array *op_array, zend_string *nam
op.constant = zend_add_literal(CG(active_op_array), &_c); \
} while (0)
-void zend_stop_lexing(void) {
+void zend_stop_lexing(void)
+{
+ if(LANG_SCNG(on_event)) LANG_SCNG(on_event)(ON_STOP, END, 0);
+
LANG_SCNG(yy_cursor) = LANG_SCNG(yy_limit);
}
-static inline void zend_begin_loop(void) /* {{{ */
+static inline void zend_begin_loop(const znode *loop_var) /* {{{ */
{
zend_brk_cont_element *brk_cont_element;
- int parent;
+ int parent = CG(context).current_brk_cont;
- parent = CG(context).current_brk_cont;
CG(context).current_brk_cont = CG(active_op_array)->last_brk_cont;
brk_cont_element = get_next_brk_cont_element(CG(active_op_array));
- brk_cont_element->start = get_next_op_number(CG(active_op_array));
brk_cont_element->parent = parent;
+
+ if (loop_var) {
+ zend_stack_push(&CG(loop_var_stack), loop_var);
+ brk_cont_element->start = get_next_op_number(CG(active_op_array));
+ } else {
+ /* The start field is used to free temporary variables in case of exceptions.
+ * We won't try to free something of we don't have loop variable. */
+ brk_cont_element->start = -1;
+ }
}
/* }}} */
-static inline void zend_end_loop(int cont_addr, int has_loop_var) /* {{{ */
+static inline void zend_end_loop(int cont_addr) /* {{{ */
{
- if (!has_loop_var) {
- /* The start fileld is used to free temporary variables in case of exceptions.
- * We won't try to free something of we don't have loop variable.
- */
- CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].start = -1;
+ zend_brk_cont_element *brk_cont_element
+ = &CG(active_op_array)->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));
+ CG(context).current_brk_cont = brk_cont_element->parent;
+
+ if (brk_cont_element->start >= 0) {
+ zend_stack_del_top(&CG(loop_var_stack));
}
- CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].cont = cont_addr;
- CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].brk = get_next_op_number(CG(active_op_array));
- CG(context).current_brk_cont = CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].parent;
}
/* }}} */
@@ -863,8 +855,11 @@ zend_string *zend_resolve_class_name(zend_string *name, uint32_t type) /* {{{ */
zend_string *zend_resolve_class_name_ast(zend_ast *ast) /* {{{ */
{
- zend_string *name = zend_ast_get_str(ast);
- return zend_resolve_class_name(name, ast->attr);
+ zval *class_name = zend_ast_get_zval(ast);
+ if (Z_TYPE_P(class_name) != IS_STRING) {
+ zend_error_noreturn(E_COMPILE_ERROR, "Illegal class name");
+ }
+ return zend_resolve_class_name(Z_STR_P(class_name), ast->attr);
}
/* }}} */
@@ -1325,14 +1320,10 @@ static inline zend_bool zend_is_scope_known() /* {{{ */
return 0;
}
- if (!CG(active_op_array)->function_name) {
- /* A file/eval will be run in the including/eval'ing scope */
- return 0;
- }
-
if (!CG(active_class_entry)) {
- /* Not being in a scope is a known scope */
- return 1;
+ /* The scope is known if we're in a free function (no scope), but not if we're in
+ * a file/eval (which inherits including/eval'ing scope). */
+ return CG(active_op_array)->function_name != NULL;
}
/* For traits self etc refers to the using class, not the trait itself */
@@ -1353,6 +1344,88 @@ static inline zend_bool class_name_refers_to_active_ce(zend_string *class_name,
}
/* }}} */
+uint32_t zend_get_class_fetch_type(zend_string *name) /* {{{ */
+{
+ if (zend_string_equals_literal_ci(name, "self")) {
+ return ZEND_FETCH_CLASS_SELF;
+ } else if (zend_string_equals_literal_ci(name, "parent")) {
+ return ZEND_FETCH_CLASS_PARENT;
+ } else if (zend_string_equals_literal_ci(name, "static")) {
+ return ZEND_FETCH_CLASS_STATIC;
+ } else {
+ return ZEND_FETCH_CLASS_DEFAULT;
+ }
+}
+/* }}} */
+
+static uint32_t zend_get_class_fetch_type_ast(zend_ast *name_ast) /* {{{ */
+{
+ /* Fully qualified names are always default refs */
+ if (name_ast->attr == ZEND_NAME_FQ) {
+ return ZEND_FETCH_CLASS_DEFAULT;
+ }
+
+ return zend_get_class_fetch_type(zend_ast_get_str(name_ast));
+}
+/* }}} */
+
+static void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */
+{
+ if (fetch_type != ZEND_FETCH_CLASS_DEFAULT && !CG(active_class_entry) && zend_is_scope_known()) {
+ zend_error_noreturn(E_COMPILE_ERROR, "Cannot use \"%s\" when no class scope is active",
+ fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
+ fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
+ }
+}
+/* }}} */
+
+static zend_bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *class_ast, zend_ast *name_ast, zend_bool constant) /* {{{ */
+{
+ uint32_t fetch_type;
+
+ if (name_ast->kind != ZEND_AST_ZVAL) {
+ return 0;
+ }
+
+ if (!zend_string_equals_literal_ci(zend_ast_get_str(name_ast), "class")) {
+ return 0;
+ }
+
+ if (class_ast->kind != ZEND_AST_ZVAL) {
+ zend_error_noreturn(E_COMPILE_ERROR,
+ "Dynamic class names are not allowed in compile-time ::class fetch");
+ }
+
+ fetch_type = zend_get_class_fetch_type(zend_ast_get_str(class_ast));
+ zend_ensure_valid_class_fetch_type(fetch_type);
+
+ switch (fetch_type) {
+ case ZEND_FETCH_CLASS_SELF:
+ if (constant || (CG(active_class_entry) && zend_is_scope_known())) {
+ ZVAL_STR_COPY(zv, CG(active_class_entry)->name);
+ } else {
+ ZVAL_NULL(zv);
+ }
+ return 1;
+ case ZEND_FETCH_CLASS_STATIC:
+ case ZEND_FETCH_CLASS_PARENT:
+ if (constant) {
+ zend_error_noreturn(E_COMPILE_ERROR,
+ "%s::class cannot be used for compile-time class name resolution",
+ fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
+ );
+ } else {
+ ZVAL_NULL(zv);
+ }
+ return 1;
+ case ZEND_FETCH_CLASS_DEFAULT:
+ ZVAL_STR(zv, zend_resolve_class_name_ast(class_ast));
+ return 1;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+}
+/* }}} */
+
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);
@@ -1385,18 +1458,7 @@ static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name,
}
/* }}} */
-void zend_init_list(void *result, void *item) /* {{{ */
-{
- void** list = emalloc(sizeof(void*) * 2);
-
- list[0] = item;
- list[1] = NULL;
-
- *(void**)result = list;
-}
-/* }}} */
-
-void zend_add_to_list(void *result, void *item) /* {{{ */
+static void zend_add_to_list(void *result, void *item) /* {{{ */
{
void** list = *(void**)result;
size_t n = 0;
@@ -1633,41 +1695,6 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify
}
/* }}} */
-uint32_t zend_get_class_fetch_type(zend_string *name) /* {{{ */
-{
- if (zend_string_equals_literal_ci(name, "self")) {
- return ZEND_FETCH_CLASS_SELF;
- } else if (zend_string_equals_literal_ci(name, "parent")) {
- return ZEND_FETCH_CLASS_PARENT;
- } else if (zend_string_equals_literal_ci(name, "static")) {
- return ZEND_FETCH_CLASS_STATIC;
- } else {
- return ZEND_FETCH_CLASS_DEFAULT;
- }
-}
-/* }}} */
-
-static uint32_t zend_get_class_fetch_type_ast(zend_ast *name_ast) /* {{{ */
-{
- /* Fully qualified names are always default refs */
- if (name_ast->attr == ZEND_NAME_FQ) {
- return ZEND_FETCH_CLASS_DEFAULT;
- }
-
- return zend_get_class_fetch_type(zend_ast_get_str(name_ast));
-}
-/* }}} */
-
-static void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */
-{
- if (fetch_type != ZEND_FETCH_CLASS_DEFAULT && !CG(active_class_entry) && zend_is_scope_known()) {
- zend_error_noreturn(E_COMPILE_ERROR, "Cannot use \"%s\" when no class scope is active",
- fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
- fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
- }
-}
-/* }}} */
-
ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_array, uint32_t var) /* {{{ */
{
return op_array->vars[EX_VAR_TO_NUM(var)];
@@ -2172,14 +2199,6 @@ static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint
znode name_node;
zend_op *opline;
- /* there is a chance someone is accessing $this */
- if (ast->kind != ZEND_AST_ZVAL
- && CG(active_op_array)->scope && CG(active_op_array)->this_var == (uint32_t)-1
- ) {
- zend_string *key = zend_string_init("this", sizeof("this") - 1, 0);
- CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), key);
- }
-
zend_compile_expr(&name_node, name_ast);
if (name_node.op_type == IS_CONST) {
convert_to_string(&name_node.u.constant);
@@ -2191,10 +2210,18 @@ static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint
opline = zend_emit_op(result, ZEND_FETCH_R, &name_node, NULL);
}
- opline->extended_value = ZEND_FETCH_LOCAL;
- if (name_node.op_type == IS_CONST) {
- if (zend_is_auto_global(Z_STR(name_node.u.constant))) {
- opline->extended_value = ZEND_FETCH_GLOBAL;
+ if (name_node.op_type == IS_CONST &&
+ zend_is_auto_global(Z_STR(name_node.u.constant))) {
+
+ opline->extended_value = ZEND_FETCH_GLOBAL;
+ } else {
+ opline->extended_value = ZEND_FETCH_LOCAL;
+ /* there is a chance someone is accessing $this */
+ if (ast->kind != ZEND_AST_ZVAL
+ && CG(active_op_array)->scope && CG(active_op_array)->this_var == (uint32_t)-1
+ ) {
+ zend_string *key = zend_string_init("this", sizeof("this") - 1, 0);
+ CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), key);
}
}
@@ -2873,7 +2900,13 @@ int zend_compile_func_strlen(znode *result, zend_ast_list *args) /* {{{ */
}
zend_compile_expr(&arg_node, args->child[0]);
- zend_emit_op_tmp(result, ZEND_STRLEN, &arg_node, NULL);
+ if (arg_node.op_type == IS_CONST && Z_TYPE(arg_node.u.constant) == IS_STRING) {
+ result->op_type = IS_CONST;
+ ZVAL_LONG(&result->u.constant, Z_STRLEN(arg_node.u.constant));
+ zval_dtor(&arg_node.u.constant);
+ } else {
+ zend_emit_op_tmp(result, ZEND_STRLEN, &arg_node, NULL);
+ }
return SUCCESS;
}
/* }}} */
@@ -3452,17 +3485,7 @@ void zend_compile_unset(zend_ast *ast) /* {{{ */
static void zend_free_foreach_and_switch_variables(void) /* {{{ */
{
- uint32_t opnum_start, opnum_end, i;
-
- opnum_start = get_next_op_number(CG(active_op_array));
-
zend_stack_apply(&CG(loop_var_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_loop_var);
-
- opnum_end = get_next_op_number(CG(active_op_array));
-
- for (i = opnum_start; i < opnum_end; ++i) {
- CG(active_op_array)->opcodes[i].extended_value |= EXT_TYPE_FREE_ON_RETURN;
- }
}
/* }}} */
@@ -3535,26 +3558,27 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
{
zend_ast *depth_ast = ast->child[0];
- znode depth_node;
zend_op *opline;
+ int depth;
ZEND_ASSERT(ast->kind == ZEND_AST_BREAK || ast->kind == ZEND_AST_CONTINUE);
if (depth_ast) {
+ zval *depth_zv;
if (depth_ast->kind != ZEND_AST_ZVAL) {
zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator with non-constant operand "
"is no longer supported", ast->kind == ZEND_AST_BREAK ? "break" : "continue");
}
- zend_compile_expr(&depth_node, depth_ast);
-
- if (Z_TYPE(depth_node.u.constant) != IS_LONG || Z_LVAL(depth_node.u.constant) < 1) {
+ depth_zv = zend_ast_get_zval(depth_ast);
+ if (Z_TYPE_P(depth_zv) != IS_LONG || Z_LVAL_P(depth_zv) < 1) {
zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator accepts only positive numbers",
ast->kind == ZEND_AST_BREAK ? "break" : "continue");
}
+
+ depth = Z_LVAL_P(depth_zv);
} else {
- depth_node.op_type = IS_CONST;
- ZVAL_LONG(&depth_node.u.constant, 1);
+ depth = 1;
}
if (CG(context).current_brk_cont == -1) {
@@ -3562,20 +3586,27 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
ast->kind == ZEND_AST_BREAK ? "break" : "continue");
} else {
int array_offset = CG(context).current_brk_cont;
- zend_long nest_level = Z_LVAL(depth_node.u.constant);
+ zend_long nest_level = depth;
+ znode *loop_var = zend_stack_top(&CG(loop_var_stack));
do {
if (array_offset == -1) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot '%s' %d level%s",
ast->kind == ZEND_AST_BREAK ? "break" : "continue",
- Z_LVAL(depth_node.u.constant), (Z_LVAL(depth_node.u.constant) == 1) ? "" : "s");
+ depth, depth == 1 ? "" : "s");
}
+
+ if (nest_level > 1 && CG(active_op_array)->brk_cont_array[array_offset].start >= 0) {
+ generate_free_loop_var(loop_var);
+ loop_var--;
+ }
+
array_offset = CG(active_op_array)->brk_cont_array[array_offset].parent;
} while (--nest_level > 0);
}
- opline = zend_emit_op(NULL, ast->kind == ZEND_AST_BREAK ? ZEND_BRK : ZEND_CONT,
- NULL, &depth_node);
- opline->op1.opline_num = CG(context).current_brk_cont;
+ opline = zend_emit_op(NULL, ast->kind == ZEND_AST_BREAK ? ZEND_BRK : ZEND_CONT, NULL, NULL);
+ opline->op1.num = CG(context).current_brk_cont;
+ opline->op2.num = depth;
}
/* }}} */
@@ -3620,7 +3651,7 @@ void zend_compile_while(zend_ast *ast) /* {{{ */
opnum_jmp = zend_emit_jump(0);
- zend_begin_loop();
+ zend_begin_loop(NULL);
opnum_start = get_next_op_number(CG(active_op_array));
zend_compile_stmt(stmt_ast);
@@ -3631,7 +3662,7 @@ void zend_compile_while(zend_ast *ast) /* {{{ */
zend_emit_cond_jump(ZEND_JMPNZ, &cond_node, opnum_start);
- zend_end_loop(opnum_cond, 0);
+ zend_end_loop(opnum_cond);
}
/* }}} */
@@ -3643,7 +3674,7 @@ void zend_compile_do_while(zend_ast *ast) /* {{{ */
znode cond_node;
uint32_t opnum_start, opnum_cond;
- zend_begin_loop();
+ zend_begin_loop(NULL);
opnum_start = get_next_op_number(CG(active_op_array));
zend_compile_stmt(stmt_ast);
@@ -3653,7 +3684,7 @@ void zend_compile_do_while(zend_ast *ast) /* {{{ */
zend_emit_cond_jump(ZEND_JMPNZ, &cond_node, opnum_start);
- zend_end_loop(opnum_cond, 0);
+ zend_end_loop(opnum_cond);
}
/* }}} */
@@ -3694,7 +3725,7 @@ void zend_compile_for(zend_ast *ast) /* {{{ */
opnum_jmp = zend_emit_jump(0);
- zend_begin_loop();
+ zend_begin_loop(NULL);
opnum_start = get_next_op_number(CG(active_op_array));
zend_compile_stmt(stmt_ast);
@@ -3709,7 +3740,7 @@ void zend_compile_for(zend_ast *ast) /* {{{ */
zend_emit_cond_jump(ZEND_JMPNZ, &result, opnum_start);
- zend_end_loop(opnum_loop, 0);
+ zend_end_loop(opnum_loop);
}
/* }}} */
@@ -3753,9 +3784,6 @@ 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);
- reset_node.flag = 1; /* generate FE_FREE */
- zend_stack_push(&CG(loop_var_stack), &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);
@@ -3779,7 +3807,8 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */
zend_emit_assign_znode(key_ast, &key_node);
}
- zend_begin_loop();
+ reset_node.flag = 1; /* generate FE_FREE */
+ zend_begin_loop(&reset_node);
zend_compile_stmt(stmt_ast);
@@ -3791,10 +3820,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, 1);
+ zend_end_loop(opnum_fetch);
generate_free_loop_var(&reset_node);
- zend_stack_del_top(&CG(loop_var_stack));
}
/* }}} */
@@ -3855,10 +3883,8 @@ void zend_compile_switch(zend_ast *ast) /* {{{ */
zend_compile_expr(&expr_node, expr_ast);
- expr_node.flag = 0;
- zend_stack_push(&CG(loop_var_stack), &expr_node);
-
- zend_begin_loop();
+ expr_node.flag = 0; /* Generate normal FREE */
+ zend_begin_loop(&expr_node);
case_node.op_type = IS_TMP_VAR;
case_node.u.op.var = get_temporary_variable(CG(active_op_array));
@@ -3917,16 +3943,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)), 1);
+ zend_end_loop(get_next_op_number(CG(active_op_array)));
if (expr_node.op_type == IS_VAR || expr_node.op_type == IS_TMP_VAR) {
- zend_emit_op(NULL, ZEND_FREE,
- &expr_node, NULL);
+ zend_emit_op(NULL, ZEND_FREE, &expr_node, NULL);
} else if (expr_node.op_type == IS_CONST) {
zval_dtor(&expr_node.u.constant);
}
- zend_stack_del_top(&CG(loop_var_stack));
efree(jmpnz_opnums);
}
/* }}} */
@@ -4198,6 +4222,37 @@ ZEND_API void zend_set_function_arg_flags(zend_function *func) /* {{{ */
}
/* }}} */
+
+static void zend_compile_typename(zend_ast *ast, zend_arg_info *arg_info) /* {{{ */
+{
+ if (ast->kind == ZEND_AST_TYPE) {
+ arg_info->type_hint = ast->attr;
+ } else {
+ zend_string *class_name = zend_ast_get_str(ast);
+ zend_uchar type = zend_lookup_builtin_type_by_name(class_name);
+
+ if (type != 0) {
+ arg_info->type_hint = type;
+ } else {
+ uint32_t fetch_type = zend_get_class_fetch_type_ast(ast);
+ if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
+ class_name = zend_resolve_class_name_ast(ast);
+ zend_assert_valid_class_name(class_name);
+ arg_info->lower_class_name = zend_string_tolower(class_name);
+ } else {
+ zend_ensure_valid_class_fetch_type(fetch_type);
+ zend_string_addref(class_name);
+ arg_info->lower_class_name = NULL;
+ }
+
+ arg_info->type_hint = IS_OBJECT;
+ arg_info->class_name = class_name;
+ }
+ }
+}
+/* }}} */
+
+
void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
{
zend_ast_list *list = zend_ast_get_list(ast);
@@ -4215,28 +4270,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
arg_infos->allow_null = 0;
arg_infos->class_name = NULL;
- if (return_type_ast->kind == ZEND_AST_TYPE) {
- arg_infos->type_hint = return_type_ast->attr;
- } else {
- zend_string *class_name = zend_ast_get_str(return_type_ast);
- zend_uchar type = zend_lookup_scalar_typehint_by_name(class_name);
-
- if (type != 0) {
- arg_infos->type_hint = type;
- } else {
- uint32_t fetch_type = zend_get_class_fetch_type_ast(return_type_ast);
- if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
- class_name = zend_resolve_class_name_ast(return_type_ast);
- zend_assert_valid_class_name(class_name);
- } else {
- zend_ensure_valid_class_fetch_type(fetch_type);
- zend_string_addref(class_name);
- }
-
- arg_infos->type_hint = IS_OBJECT;
- arg_infos->class_name = class_name;
- }
- }
+ zend_compile_typename(return_type_ast, arg_infos);
arg_infos++;
op_array->fn_flags |= ZEND_ACC_HAS_RETURN_TYPE;
@@ -4327,8 +4361,9 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS;
arg_info->allow_null = has_null_default;
+ zend_compile_typename(type_ast, arg_info);
+
if (type_ast->kind == ZEND_AST_TYPE) {
- arg_info->type_hint = type_ast->attr;
if (arg_info->type_hint == IS_ARRAY) {
if (default_ast && !has_null_default
&& Z_TYPE(default_node.u.constant) != IS_ARRAY
@@ -4344,32 +4379,14 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
}
}
} else {
- zend_string *class_name = zend_ast_get_str(type_ast);
- zend_uchar type;
-
- type = zend_lookup_scalar_typehint_by_name(class_name);
- if (type != 0) {
- arg_info->type_hint = type;
- } else {
- uint32_t fetch_type = zend_get_class_fetch_type_ast(type_ast);
- if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
- class_name = zend_resolve_class_name_ast(type_ast);
- zend_assert_valid_class_name(class_name);
- } else {
- zend_ensure_valid_class_fetch_type(fetch_type);
- zend_string_addref(class_name);
- }
-
- arg_info->type_hint = IS_OBJECT;
- arg_info->class_name = class_name;
- }
if (default_ast && !has_null_default && !Z_CONSTANT(default_node.u.constant)) {
if (arg_info->class_name) {
zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
"with a class type hint can only be NULL");
} else if (!ZEND_SAME_FAKE_TYPE(arg_info->type_hint, Z_TYPE(default_node.u.constant))) {
zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
- "with a %s type hint can only be %s or NULL", class_name->val, class_name->val);
+ "with a %s type hint can only be %s or NULL",
+ zend_get_type_by_const(arg_info->type_hint), zend_get_type_by_const(arg_info->type_hint));
}
}
}
@@ -4774,6 +4791,11 @@ void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */
zend_string *name = zend_ast_get_str(name_ast);
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");
+ }
+
zend_const_expr_to_zval(&value_zv, value_ast);
name = zend_new_interned_string_safe(name);
@@ -4953,19 +4975,12 @@ static zend_string *zend_generate_anon_class_name(unsigned char *lex_pos) /* {{{
{
zend_string *result;
char char_pos_buf[32];
- size_t filename_len, char_pos_len = zend_sprintf(char_pos_buf, "%p", lex_pos);
+ size_t char_pos_len = zend_sprintf(char_pos_buf, "%p", lex_pos);
+ zend_string *filename = CG(active_op_array)->filename;
- const char *filename;
- if (CG(active_op_array)->filename) {
- filename = CG(active_op_array)->filename->val;
- filename_len = CG(active_op_array)->filename->len;
- } else {
- filename = "-";
- filename_len = sizeof("-") - 1;
- }
/* NULL, name length, filename length, last accepting char position length */
- result = zend_string_alloc(sizeof("class@anonymous") + filename_len + char_pos_len, 0);
- sprintf(result->val, "class@anonymous%c%s%s", '\0', filename, char_pos_buf);
+ result = zend_string_alloc(sizeof("class@anonymous") + filename->len + char_pos_len, 0);
+ sprintf(result->val, "class@anonymous%c%s%s", '\0', filename->val, char_pos_buf);
return zend_new_interned_string(result);
}
/* }}} */
@@ -4976,8 +4991,7 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
zend_ast *extends_ast = decl->child[0];
zend_ast *implements_ast = decl->child[1];
zend_ast *stmt_ast = decl->child[2];
-
- zend_string *name = decl->name, *lcname, *import_name = NULL;
+ zend_string *name, *lcname, *import_name = NULL;
zend_class_entry *ce = zend_arena_alloc(&CG(arena), sizeof(zend_class_entry));
zend_op *opline;
znode declare_node, extends_node;
@@ -4985,43 +4999,37 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
zend_class_entry *original_ce = CG(active_class_entry);
znode original_implementing_class = FC(implementing_class);
- if (decl->flags & ZEND_ACC_ANON_CLASS) {
- decl->name = name = zend_generate_anon_class_name(decl->lex_pos);
-
- /* Serialization is not supported for anonymous classes */
- ce->serialize = zend_class_serialize_deny;
- ce->unserialize = zend_class_unserialize_deny;
- }
-
- if (CG(active_class_entry) && !(decl->flags & ZEND_ACC_ANON_CLASS)) {
- zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be nested");
- }
-
- zend_assert_valid_class_name(name);
+ if (EXPECTED((decl->flags & ZEND_ACC_ANON_CLASS) == 0)) {
+ if (CG(active_class_entry)) {
+ zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be nested");
+ }
+ name = decl->name;
+ zend_assert_valid_class_name(name);
+ lcname = zend_string_tolower(name);
+ if (FC(current_namespace)) {
+ name = zend_prefix_with_ns(name);
- lcname = zend_string_tolower(name);
+ zend_string_release(lcname);
+ lcname = zend_string_tolower(name);
+ } else {
+ zend_string_addref(name);
+ }
- if (FC(imports)) {
- import_name = zend_hash_find_ptr(FC(imports), lcname);
- }
+ if (FC(imports)) {
+ import_name = zend_hash_find_ptr(FC(imports), lcname);
+ }
- if (FC(current_namespace)) {
- name = zend_prefix_with_ns(name);
+ if (import_name && !zend_string_equals_ci(lcname, import_name)) {
+ zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s "
+ "because the name is already in use", name->val);
+ }
- zend_string_release(lcname);
- lcname = zend_string_tolower(name);
+ name = zend_new_interned_string(name);
+ lcname = zend_new_interned_string(lcname);
} else {
- zend_string_addref(name);
- }
-
- if (import_name && !zend_string_equals_ci(lcname, import_name)) {
- zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s "
- "because the name is already in use", name->val);
+ lcname = name = zend_generate_anon_class_name(decl->lex_pos);
}
- name = zend_new_interned_string(name);
- lcname = zend_new_interned_string(lcname);
-
ce->type = ZEND_USER_CLASS;
ce->name = name;
zend_initialize_class_data(ce, 1);
@@ -5030,10 +5038,17 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
ce->info.user.filename = zend_get_compiled_filename();
ce->info.user.line_start = decl->start_lineno;
ce->info.user.line_end = decl->end_lineno;
+
if (decl->doc_comment) {
ce->info.user.doc_comment = zend_string_copy(decl->doc_comment);
}
+ if (UNEXPECTED((decl->flags & ZEND_ACC_ANON_CLASS))) {
+ /* Serialization is not supported for anonymous classes */
+ ce->serialize = zend_class_serialize_deny;
+ ce->unserialize = zend_class_unserialize_deny;
+ }
+
if (extends_ast) {
if (!zend_is_const_default_class_ref(extends_ast)) {
zend_string *extends_name = zend_ast_get_str(extends_ast);
@@ -5576,6 +5591,13 @@ static inline void zend_ct_eval_binary_op(zval *result, uint32_t opcode, zval *o
}
/* }}} */
+static inline void zend_ct_eval_unary_op(zval *result, uint32_t opcode, zval *op) /* {{{ */
+{
+ unary_op_type fn = get_unary_op(opcode);
+ fn(result, op);
+}
+/* }}} */
+
static inline void zend_ct_eval_unary_pm(zval *result, zend_ast_kind kind, zval *op) /* {{{ */
{
binary_op_type fn = kind == ZEND_AST_UNARY_PLUS
@@ -5719,6 +5741,15 @@ void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */
}
}
}
+ if (opcode == ZEND_CONCAT) {
+ /* convert constant operands to strings at compile-time */
+ if (left_node.op_type == IS_CONST) {
+ convert_to_string(&left_node.u.constant);
+ }
+ if (right_node.op_type == IS_CONST) {
+ convert_to_string(&right_node.u.constant);
+ }
+ }
zend_emit_op_tmp(result, opcode, &left_node, &right_node);
} while (0);
}
@@ -5760,6 +5791,14 @@ void zend_compile_unary_op(znode *result, zend_ast *ast) /* {{{ */
znode expr_node;
zend_compile_expr(&expr_node, expr_ast);
+ if (expr_node.op_type == IS_CONST) {
+ result->op_type = IS_CONST;
+ zend_ct_eval_unary_op(&result->u.constant, opcode,
+ &expr_node.u.constant);
+ zval_ptr_dtor(&expr_node.u.constant);
+ return;
+ }
+
zend_emit_op_tmp(result, opcode, &expr_node, NULL);
}
/* }}} */
@@ -5801,6 +5840,28 @@ void zend_compile_short_circuiting(znode *result, zend_ast *ast) /* {{{ */
zend_compile_expr(&left_node, left_ast);
+ if (left_node.op_type == IS_CONST) {
+ if ((ast->kind == ZEND_AST_AND && !zend_is_true(&left_node.u.constant))
+ || (ast->kind == ZEND_AST_OR && zend_is_true(&left_node.u.constant))) {
+ result->op_type = IS_CONST;
+ ZVAL_BOOL(&result->u.constant, zend_is_true(&left_node.u.constant));
+ } else {
+ zend_compile_expr(&right_node, right_ast);
+
+ if (right_node.op_type == IS_CONST) {
+ result->op_type = IS_CONST;
+ ZVAL_BOOL(&result->u.constant, zend_is_true(&right_node.u.constant));
+
+ zval_ptr_dtor(&right_node.u.constant);
+ } else {
+ zend_emit_op(result, ZEND_BOOL, &right_node, NULL);
+ }
+ }
+
+ zval_ptr_dtor(&left_node.u.constant);
+ return;
+ }
+
opnum_jmpz = get_next_op_number(CG(active_op_array));
opline_jmpz = zend_emit_op(NULL, ast->kind == ZEND_AST_AND ? ZEND_JMPZ_EX : ZEND_JMPNZ_EX,
&left_node, NULL);
@@ -5811,10 +5872,26 @@ void zend_compile_short_circuiting(znode *result, zend_ast *ast) /* {{{ */
opline_jmpz->result.var = get_temporary_variable(CG(active_op_array));
opline_jmpz->result_type = IS_TMP_VAR;
}
- GET_NODE(result, opline_jmpz->result);
zend_compile_expr(&right_node, right_ast);
+ if (right_node.op_type == IS_CONST && opnum_jmpz == get_next_op_number(CG(active_op_array)) - 1) {
+ if ((ast->kind == ZEND_AST_AND && !zend_is_true(&right_node.u.constant))
+ || (ast->kind == ZEND_AST_OR && zend_is_true(&right_node.u.constant))) {
+ CG(active_op_array)->last--;
+ result->op_type = IS_CONST;
+ ZVAL_BOOL(&result->u.constant, zend_is_true(&right_node.u.constant));
+ } else {
+ opline_jmpz->opcode = ZEND_BOOL;
+ zend_make_var_result(result, opline_jmpz);
+ }
+
+ zval_ptr_dtor(&right_node.u.constant);
+ return;
+ }
+
+ GET_NODE(result, opline_jmpz->result);
+
opline_bool = zend_emit_op(NULL, ZEND_BOOL, &right_node, NULL);
SET_NODE(opline_bool->result, result);
@@ -6340,6 +6417,16 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
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) {
+ zend_op *opline = zend_emit_op_tmp(result, ZEND_FETCH_CLASS_NAME, NULL, NULL);
+ opline->extended_value = zend_get_class_fetch_type(zend_ast_get_str(class_ast));
+ } else {
+ result->op_type = IS_CONST;
+ }
+ return;
+ }
+
zend_eval_const_expr(&class_ast);
zend_eval_const_expr(&const_ast);
@@ -6351,6 +6438,10 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
return;
}
}
+ 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;
@@ -6563,7 +6654,7 @@ zend_bool zend_is_allowed_in_const_expr(zend_ast_kind kind) /* {{{ */
|| kind == ZEND_AST_CONDITIONAL || kind == ZEND_AST_DIM
|| kind == ZEND_AST_ARRAY || kind == ZEND_AST_ARRAY_ELEM
|| kind == ZEND_AST_CONST || kind == ZEND_AST_CLASS_CONST
- || kind == ZEND_AST_RESOLVE_CLASS_NAME || kind == ZEND_AST_MAGIC_CONST;
+ || kind == ZEND_AST_MAGIC_CONST;
}
/* }}} */
@@ -6582,6 +6673,11 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */
"Dynamic class names are not allowed in compile-time class constant references");
}
+ if (zend_try_compile_const_expr_resolve_class_name(&result, class_ast, const_ast, 1)) {
+ *ast_ptr = zend_ast_create_zval(&result);
+ return;
+ }
+
class_name = zend_ast_get_str(class_ast);
fetch_type = zend_get_class_fetch_type(class_name);
@@ -6637,36 +6733,6 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */
}
/* }}} */
-void zend_compile_const_expr_resolve_class_name(zend_ast **ast_ptr) /* {{{ */
-{
- zend_ast *ast = *ast_ptr;
- zend_ast *name_ast = ast->child[0];
- zval result;
- uint32_t fetch_type = zend_get_class_fetch_type(zend_ast_get_str(name_ast));
- zend_ensure_valid_class_fetch_type(fetch_type);
-
- switch (fetch_type) {
- case ZEND_FETCH_CLASS_SELF:
- ZVAL_STR_COPY(&result, CG(active_class_entry)->name);
- break;
- case ZEND_FETCH_CLASS_STATIC:
- case ZEND_FETCH_CLASS_PARENT:
- zend_error_noreturn(E_COMPILE_ERROR,
- "%s::class cannot be used for compile-time class name resolution",
- fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
- );
- break;
- case ZEND_FETCH_CLASS_DEFAULT:
- ZVAL_STR(&result, zend_resolve_class_name_ast(name_ast));
- break;
- EMPTY_SWITCH_DEFAULT_CASE()
- }
-
- zend_ast_destroy(ast);
- *ast_ptr = zend_ast_create_zval(&result);
-}
-/* }}} */
-
void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */
{
zend_ast *ast = *ast_ptr;
@@ -6705,9 +6771,6 @@ void zend_compile_const_expr(zend_ast **ast_ptr) /* {{{ */
case ZEND_AST_CONST:
zend_compile_const_expr_const(ast_ptr);
break;
- case ZEND_AST_RESOLVE_CLASS_NAME:
- zend_compile_const_expr_resolve_class_name(ast_ptr);
- break;
case ZEND_AST_MAGIC_CONST:
zend_compile_const_expr_magic_const(ast_ptr);
break;
@@ -6982,9 +7045,6 @@ void zend_compile_expr(znode *result, zend_ast *ast) /* {{{ */
case ZEND_AST_CLASS_CONST:
zend_compile_class_const(result, ast);
return;
- case ZEND_AST_RESOLVE_CLASS_NAME:
- zend_compile_resolve_class_name(result, ast);
- return;
case ZEND_AST_ENCAPS_LIST:
zend_compile_encaps_list(result, ast);
return;
@@ -7154,9 +7214,22 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
zend_ast *name_ast = ast->child[1];
zend_string *resolved_name;
+ if (zend_try_compile_const_expr_resolve_class_name(&result, class_ast, name_ast, 0)) {
+ if (Z_TYPE(result) == IS_NULL) {
+ return;
+ } else {
+ break;
+ }
+ }
+
zend_eval_const_expr(&class_ast);
zend_eval_const_expr(&name_ast);
+ if (name_ast->kind == ZEND_AST_ZVAL && zend_string_equals_literal_ci(zend_ast_get_str(name_ast), "class")) {
+ zend_error_noreturn(E_COMPILE_ERROR,
+ "Dynamic class names are not allowed in compile-time ::class fetch");
+ }
+
if (class_ast->kind != ZEND_AST_ZVAL || name_ast->kind != ZEND_AST_ZVAL) {
return;
}
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 2027bfdfd2..eccbb84aff 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -183,16 +183,6 @@ typedef struct _zend_try_catch_element {
uint32_t finally_end;
} zend_try_catch_element;
-#if SIZEOF_ZEND_LONG == 8
-# ifdef _WIN32
-# define THIS_HASHVAL 6385726429Ui64
-# else
-# define THIS_HASHVAL 6385726429ULL
-# endif
-#else
-#define THIS_HASHVAL 2090759133UL
-#endif
-
/* method flags (types) */
#define ZEND_ACC_STATIC 0x01
#define ZEND_ACC_ABSTRACT 0x02
@@ -307,6 +297,7 @@ typedef struct _zend_internal_arg_info {
zend_uchar pass_by_reference;
zend_bool allow_null;
zend_bool is_variadic;
+ void *reserved; /* to align with zend_arg_info */
} zend_internal_arg_info;
/* arg_info for user functions */
@@ -317,6 +308,7 @@ typedef struct _zend_arg_info {
zend_uchar pass_by_reference;
zend_bool allow_null;
zend_bool is_variadic;
+ zend_string *lower_class_name;
} zend_arg_info;
/* the following structure repeats the layout of zend_internal_arg_info,
@@ -711,10 +703,6 @@ 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_API void zend_do_delayed_early_binding(const zend_op_array *op_array);
-/* Functions for a null terminated pointer list, used for traits parsing and compilation */
-void zend_init_list(void *result, void *item);
-void zend_add_to_list(void *result, void *item);
-
void zend_do_extended_info(void);
void zend_do_extended_fcall_begin(void);
void zend_do_extended_fcall_end(void);
@@ -884,8 +872,6 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name);
#define ZEND_FETCH_ARG_MASK 0x000fffff
-#define EXT_TYPE_FREE_ON_RETURN (1<<2)
-
#define ZEND_MEMBER_FUNC_CALL 1<<0
#define ZEND_ARG_SEND_BY_REF (1<<0)
@@ -961,6 +947,11 @@ static zend_always_inline int zend_check_arg_send_type(const zend_function *zf,
#define ZEND_ARRAY_NOT_PACKED (1<<1)
#define ZEND_ARRAY_SIZE_SHIFT 2
+/* Pseudo-opcodes that are used only temporarily during compilation */
+#define ZEND_BRK 254
+#define ZEND_CONT 255
+
+
END_EXTERN_C()
#define ZEND_CLONE_FUNC_NAME "__clone"
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index 422c4bb5fd..ae55c1fcea 100644
--- a/Zend/zend_exceptions.c
+++ b/Zend/zend_exceptions.c
@@ -38,7 +38,7 @@ static zend_class_entry *type_error_ce;
static zend_object_handlers default_exception_handlers;
ZEND_API void (*zend_throw_exception_hook)(zval *ex);
-static zend_class_entry *zend_get_exception_base(zval *object)
+static inline zend_class_entry *zend_get_exception_base(zval *object)
{
return instanceof_function(Z_OBJCE_P(object), default_exception_ce) ? default_exception_ce : error_ce;
}
@@ -131,7 +131,7 @@ ZEND_API void zend_throw_exception_internal(zval *exception) /* {{{ */
if (!EG(current_execute_data)->func ||
!ZEND_USER_CODE(EG(current_execute_data)->func->common.type) ||
- (EG(current_execute_data)->opline+1)->opcode == ZEND_HANDLE_EXCEPTION) {
+ EG(current_execute_data)->opline->opcode == ZEND_HANDLE_EXCEPTION) {
/* no need to rethrow the exception */
return;
}
@@ -573,7 +573,7 @@ ZEND_METHOD(exception, getTraceAsString)
object = getThis();
base_ce = zend_get_exception_base(object);
- trace = zend_read_property(base_ce, getThis(), "trace", sizeof("trace")-1, 1, &rv);
+ trace = zend_read_property(base_ce, object, "trace", sizeof("trace")-1, 1, &rv);
if (Z_TYPE_P(trace) != IS_ARRAY) {
RETURN_FALSE;
}
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index d29014d3b2..e63fc2dd32 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -57,6 +57,7 @@ typedef int (ZEND_FASTCALL *incdec_t)(zval *);
#define get_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type)
#define get_zval_ptr_ptr_undef(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type)
#define get_obj_zval_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr(op_type, node, ex, should_free, type)
+#define get_obj_zval_ptr_undef(op_type, node, ex, should_free, type) _get_obj_zval_ptr_undef(op_type, node, ex, should_free, type)
#define get_obj_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr_ptr(op_type, node, ex, should_free, type)
/* Prototypes */
@@ -516,6 +517,15 @@ static inline zval *_get_obj_zval_ptr(int op_type, znode_op op, zend_execute_dat
return get_zval_ptr(op_type, op, execute_data, should_free, type);
}
+static inline zval *_get_obj_zval_ptr_undef(int op_type, znode_op op, zend_execute_data *execute_data, zend_free_op *should_free, int type)
+{
+ if (op_type == IS_UNUSED) {
+ *should_free = NULL;
+ return &EX(This);
+ }
+ return get_zval_ptr_undef(op_type, op, execute_data, should_free, type);
+}
+
static inline zval *_get_obj_zval_ptr_ptr(int op_type, znode_op node, zend_execute_data *execute_data, zend_free_op *should_free, int type)
{
if (op_type == IS_UNUSED) {
@@ -577,7 +587,12 @@ ZEND_API char * zend_verify_internal_arg_class_kind(const zend_internal_arg_info
ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, char **class_name, zend_class_entry **pce)
{
- *pce = zend_fetch_class(cur_arg_info->class_name, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
+ /* optimization to not always recalculate the lowercase name and hash */
+ if (cur_arg_info->lower_class_name) {
+ *pce = zend_hash_find_ptr(EG(class_table), cur_arg_info->lower_class_name);
+ } else { /* "extra" fetch type */
+ *pce = zend_fetch_class(cur_arg_info->class_name, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
+ }
*class_name = (*pce) ? (*pce)->name->val : cur_arg_info->class_name->val;
if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
@@ -593,7 +608,6 @@ ZEND_API void zend_verify_arg_error(const zend_function *zf, uint32_t arg_num, c
const char *fname = zf->common.function_name->val;
const char *fsep;
const char *fclass;
- zval old_arg;
if (zf->common.scope) {
fsep = "::";
@@ -604,11 +618,6 @@ ZEND_API void zend_verify_arg_error(const zend_function *zf, uint32_t arg_num, c
}
if (zf->common.type == ZEND_USER_FUNCTION) {
- if (arg) {
- ZVAL_COPY_VALUE(&old_arg, arg);
- ZVAL_UNDEF(arg);
- }
-
if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
zend_type_error("Argument %d passed to %s%s%s() must %s%s, %s%s given, called in %s on line %d",
arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind,
@@ -616,10 +625,6 @@ ZEND_API void zend_verify_arg_error(const zend_function *zf, uint32_t arg_num, c
} else {
zend_type_error("Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind);
}
-
- if (arg) {
- ZVAL_COPY_VALUE(arg, &old_arg);
- }
} else {
zend_type_error("Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind);
}
@@ -1246,6 +1251,133 @@ static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *valu
}
}
+static zend_never_inline void zend_post_incdec_overloaded_property(zval *object, zval *property, void **cache_slot, int inc, zval *result)
+{
+ if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
+ zval rv, obj;
+ zval *z;
+ zval z_copy;
+
+ ZVAL_OBJ(&obj, Z_OBJ_P(object));
+ Z_ADDREF(obj);
+ z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv);
+ if (UNEXPECTED(EG(exception))) {
+ OBJ_RELEASE(Z_OBJ(obj));
+ return;
+ }
+
+ if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
+ zval rv2;
+ zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
+ if (z == &rv) {
+ zval_ptr_dtor(&rv);
+ }
+ ZVAL_COPY_VALUE(z, value);
+ }
+ ZVAL_COPY(result, z);
+ ZVAL_DUP(&z_copy, z);
+ if (inc) {
+ increment_function(&z_copy);
+ } else {
+ decrement_function(&z_copy);
+ }
+ if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
+ Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, cache_slot);
+ OBJ_RELEASE(Z_OBJ(obj));
+ zval_ptr_dtor(&z_copy);
+ zval_ptr_dtor(z);
+ } else {
+ zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
+ ZVAL_NULL(result);
+ }
+}
+
+static zend_never_inline void zend_pre_incdec_overloaded_property(zval *object, zval *property, void **cache_slot, int inc, zval *result)
+{
+ zval rv;
+
+ if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
+ zval *z, obj;
+
+ ZVAL_OBJ(&obj, Z_OBJ_P(object));
+ Z_ADDREF(obj);
+ z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv);
+ if (UNEXPECTED(EG(exception))) {
+ OBJ_RELEASE(Z_OBJ(obj));
+ return;
+ }
+
+ if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
+ zval rv2;
+ zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
+
+ if (z == &rv) {
+ zval_ptr_dtor(&rv);
+ }
+ ZVAL_COPY_VALUE(z, value);
+ }
+ ZVAL_DEREF(z);
+ SEPARATE_ZVAL_NOREF(z);
+ if (inc) {
+ increment_function(z);
+ } else {
+ decrement_function(z);
+ }
+ if (UNEXPECTED(result)) {
+ ZVAL_COPY(result, z);
+ }
+ Z_OBJ_HT(obj)->write_property(&obj, property, z, cache_slot);
+ OBJ_RELEASE(Z_OBJ(obj));
+ zval_ptr_dtor(z);
+ } else {
+ zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
+ if (UNEXPECTED(result)) {
+ ZVAL_NULL(result);
+ }
+ }
+}
+
+static zend_never_inline void zend_assign_op_overloaded_property(zval *object, zval *property, void **cache_slot, zval *value, binary_op_type binary_op, zval *result)
+{
+ zval *z;
+ zval rv, obj;
+ zval *zptr;
+
+ ZVAL_OBJ(&obj, Z_OBJ_P(object));
+ Z_ADDREF(obj);
+ if (Z_OBJ_HT(obj)->read_property &&
+ (z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv)) != NULL) {
+ if (UNEXPECTED(EG(exception))) {
+ OBJ_RELEASE(Z_OBJ(obj));
+ return;
+ }
+ if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
+ zval rv2;
+ zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
+
+ if (z == &rv) {
+ zval_ptr_dtor(&rv);
+ }
+ ZVAL_COPY_VALUE(z, value);
+ }
+ zptr = z;
+ ZVAL_DEREF(z);
+ SEPARATE_ZVAL_NOREF(z);
+ binary_op(z, z, value);
+ Z_OBJ_HT(obj)->write_property(&obj, property, z, cache_slot);
+ if (UNEXPECTED(result)) {
+ ZVAL_COPY(result, z);
+ }
+ zval_ptr_dtor(zptr);
+ } else {
+ zend_error(E_WARNING, "Attempt to assign property of non-object");
+ if (UNEXPECTED(result)) {
+ ZVAL_NULL(result);
+ }
+ }
+ OBJ_RELEASE(Z_OBJ(obj));
+}
+
/* Utility Functions for Extensions */
static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array)
{
@@ -1311,14 +1443,14 @@ num_index:
if (retval == NULL) {
switch (type) {
case BP_VAR_R:
- zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, hval);
+ zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval);
/* break missing intentionally */
case BP_VAR_UNSET:
case BP_VAR_IS:
retval = &EG(uninitialized_zval);
break;
case BP_VAR_RW:
- zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, hval);
+ zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval);
/* break missing intentionally */
case BP_VAR_W:
retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
@@ -1458,8 +1590,8 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *
{
zval *retval;
-try_again:
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+try_array:
SEPARATE_ARRAY(container);
fetch_from_array:
if (dim == NULL) {
@@ -1472,7 +1604,14 @@ fetch_from_array:
retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type);
}
ZVAL_INDIRECT(result, retval);
- } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ return;
+ } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto try_array;
+ }
+ }
+ if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
if (type != BP_VAR_UNSET && UNEXPECTED(Z_STRLEN_P(container) == 0)) {
zval_ptr_dtor_nogc(container);
convert_to_array:
@@ -1534,9 +1673,6 @@ convert_to_array:
/* for read-mode only */
ZVAL_NULL(result);
}
- } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
- container = Z_REFVAL_P(container);
- goto try_again;
} else {
if (type == BP_VAR_UNSET) {
zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
@@ -1567,11 +1703,18 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z
{
zval *retval;
-try_again:
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+try_array:
retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type);
ZVAL_COPY(result, retval);
- } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ return;
+ } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto try_array;
+ }
+ }
+ if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
zend_long offset;
try_string_offset:
@@ -1637,9 +1780,6 @@ try_string_offset:
ZVAL_NULL(result);
}
}
- } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
- container = Z_REFVAL_P(container);
- goto try_again;
} else {
ZVAL_NULL(result);
}
@@ -1742,21 +1882,17 @@ static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_of
do {
ZEND_ASSERT(array_offset != -1);
jmp_to = &op_array->brk_cont_array[array_offset];
- if (nest_levels>1) {
+ if (nest_levels > 1 && jmp_to->start >= 0) {
zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
if (brk_opline->opcode == ZEND_FREE) {
- if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
- zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
- }
+ zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
} else if (brk_opline->opcode == ZEND_FE_FREE) {
- if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
- zval *var = EX_VAR(brk_opline->op1.var);
- if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
- zend_hash_iterator_del(Z_FE_ITER_P(var));
- }
- zval_ptr_dtor_nogc(var);
+ zval *var = EX_VAR(brk_opline->op1.var);
+ if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
+ zend_hash_iterator_del(Z_FE_ITER_P(var));
}
+ zval_ptr_dtor_nogc(var);
}
}
array_offset = jmp_to->parent;
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 706d913f72..9687a556af 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -176,8 +176,10 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
if (finally_op_num) {
zval *fast_call = ZEND_CALL_VAR(ex, ex->func->op_array.opcodes[finally_op_end].op1.var);
- Z_OBJ_P(fast_call) = NULL;
+ Z_OBJ_P(fast_call) = EG(exception);
+ EG(exception) = NULL;
fast_call->u2.lineno = (uint32_t)-1;
+
ex->opline = &ex->func->op_array.opcodes[finally_op_num];
generator->flags |= ZEND_GENERATOR_FORCED_CLOSE;
zend_generator_resume(generator);
@@ -817,7 +819,10 @@ ZEND_METHOD(Generator, current)
root = zend_generator_get_current(generator);
if (Z_TYPE(root->value) != IS_UNDEF) {
- RETURN_ZVAL_FAST(&root->value);
+ zval *value = &root->value;
+
+ ZVAL_DEREF(value);
+ ZVAL_COPY(return_value, value);
}
}
/* }}} */
@@ -838,7 +843,10 @@ ZEND_METHOD(Generator, key)
root = zend_generator_get_current(generator);
if (Z_TYPE(root->key) != IS_UNDEF) {
- RETURN_ZVAL_FAST(&root->key);
+ zval *key = &root->key;
+
+ ZVAL_DEREF(key);
+ ZVAL_COPY(return_value, key);
}
}
/* }}} */
@@ -892,7 +900,10 @@ ZEND_METHOD(Generator, send)
root = zend_generator_get_current(generator);
if (Z_TYPE(root->value) != IS_UNDEF) {
- RETURN_ZVAL_FAST(&root->value);
+ zval *value = &root->value;
+
+ ZVAL_DEREF(value);
+ ZVAL_COPY(return_value, value);
}
}
/* }}} */
@@ -923,7 +934,10 @@ ZEND_METHOD(Generator, throw)
root = zend_generator_get_current(generator);
if (Z_TYPE(root->value) != IS_UNDEF) {
- RETURN_ZVAL_FAST(&root->value);
+ zval *value = &root->value;
+
+ ZVAL_DEREF(value);
+ ZVAL_COPY(return_value, value);
}
} else {
/* If the generator is already closed throw the exception in the
@@ -1021,7 +1035,10 @@ static void zend_generator_iterator_get_key(zend_object_iterator *iterator, zval
root = zend_generator_get_current(generator);
if (Z_TYPE(root->key) != IS_UNDEF) {
- ZVAL_ZVAL(key, &root->key, 1, 0);
+ zval *zv = &root->key;
+
+ ZVAL_DEREF(zv);
+ ZVAL_COPY(key, zv);
} else {
ZVAL_NULL(key);
}
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index 326955a103..28487a2a4a 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -249,6 +249,12 @@ struct _zend_ini_scanner_globals {
int scanner_mode;
};
+typedef enum {
+ ON_TOKEN,
+ ON_FEEDBACK,
+ ON_STOP
+} zend_php_scanner_event;
+
struct _zend_php_scanner_globals {
zend_file_handle *yy_in;
zend_file_handle *yy_out;
@@ -278,6 +284,9 @@ struct _zend_php_scanner_globals {
/* initial string length after scanning to first variable */
int scanned_string_len;
+
+ /* hooks */
+ void (* on_event)(zend_php_scanner_event event, int token, int line);
};
#endif /* ZEND_GLOBALS_H */
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index 75bcb2142d..05426412fe 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -28,7 +28,7 @@
# define HT_ASSERT(c) ZEND_ASSERT(c)
#else
# define HT_ASSERT(c)
-#endif
+#endif
#if ZEND_DEBUG
/*
@@ -71,7 +71,7 @@ static void _zend_is_inconsistent(const HashTable *ht, const char *file, int lin
#define HASH_PROTECT_RECURSION(ht) \
if ((ht)->u.flags & HASH_FLAG_APPLY_PROTECTION) { \
- if ((ht)->u.flags >= (3 << 8)) { \
+ if (((ht)->u.flags & ZEND_HASH_APPLY_COUNT_MASK) >= (3 << 8)) { \
zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?");\
} \
ZEND_HASH_INC_APPLY_COUNT(ht); \
@@ -125,13 +125,13 @@ static void zend_always_inline zend_hash_real_init_ex(HashTable *ht, int packed)
HT_ASSERT(GC_REFCOUNT(ht) == 1);
ZEND_ASSERT(!((ht)->u.flags & HASH_FLAG_INITIALIZED));
if (packed) {
- (ht)->u.flags |= HASH_FLAG_INITIALIZED | HASH_FLAG_PACKED;
HT_SET_DATA_ADDR(ht, pemalloc(HT_SIZE(ht), (ht)->u.flags & HASH_FLAG_PERSISTENT));
+ (ht)->u.flags |= HASH_FLAG_INITIALIZED | HASH_FLAG_PACKED;
HT_HASH_RESET_PACKED(ht);
} else {
- (ht)->u.flags |= HASH_FLAG_INITIALIZED;
(ht)->nTableMask = -(ht)->nTableSize;
HT_SET_DATA_ADDR(ht, pemalloc(HT_SIZE(ht), (ht)->u.flags & HASH_FLAG_PERSISTENT));
+ (ht)->u.flags |= HASH_FLAG_INITIALIZED;
HT_HASH_RESET(ht);
}
}
@@ -219,7 +219,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_to_packed(HashTable *ht)
ZEND_API void ZEND_FASTCALL _zend_hash_init_ex(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC)
{
- _zend_hash_init(ht, nSize, pDestructor, persistent ZEND_FILE_LINE_CC);
+ _zend_hash_init(ht, nSize, pDestructor, persistent ZEND_FILE_LINE_RELAY_CC);
if (!bApplyProtection) {
ht->u.flags &= ~HASH_FLAG_APPLY_PROTECTION;
}
@@ -567,7 +567,7 @@ ZEND_API zval* ZEND_FASTCALL _zend_hash_add_new(HashTable *ht, zend_string *key,
ZEND_API zval* ZEND_FASTCALL _zend_hash_str_add_or_update(HashTable *ht, const char *str, size_t len, zval *pData, uint32_t flag ZEND_FILE_LINE_DC)
{
zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT);
- zval *ret = _zend_hash_add_or_update_i(ht, key, pData, flag ZEND_FILE_LINE_CC);
+ zval *ret = _zend_hash_add_or_update_i(ht, key, pData, flag ZEND_FILE_LINE_RELAY_CC);
zend_string_release(key);
return ret;
}
@@ -575,7 +575,7 @@ ZEND_API zval* ZEND_FASTCALL _zend_hash_str_add_or_update(HashTable *ht, const c
ZEND_API zval* ZEND_FASTCALL _zend_hash_str_update(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC)
{
zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT);
- zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE ZEND_FILE_LINE_CC);
+ zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE ZEND_FILE_LINE_RELAY_CC);
zend_string_release(key);
return ret;
}
@@ -583,7 +583,7 @@ ZEND_API zval* ZEND_FASTCALL _zend_hash_str_update(HashTable *ht, const char *st
ZEND_API zval* ZEND_FASTCALL _zend_hash_str_update_ind(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC)
{
zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT);
- zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_CC);
+ zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_RELAY_CC);
zend_string_release(key);
return ret;
}
@@ -591,7 +591,7 @@ ZEND_API zval* ZEND_FASTCALL _zend_hash_str_update_ind(HashTable *ht, const char
ZEND_API zval* ZEND_FASTCALL _zend_hash_str_add(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC)
{
zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT);
- zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD ZEND_FILE_LINE_CC);
+ zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD ZEND_FILE_LINE_RELAY_CC);
zend_string_release(key);
return ret;
}
@@ -599,14 +599,13 @@ ZEND_API zval* ZEND_FASTCALL _zend_hash_str_add(HashTable *ht, const char *str,
ZEND_API zval* ZEND_FASTCALL _zend_hash_str_add_new(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC)
{
zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT);
- zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD_NEW ZEND_FILE_LINE_CC);
- zend_string_release(key);
+ zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD_NEW ZEND_FILE_LINE_RELAY_CC);
+ zend_string_delref(key);
return ret;
}
ZEND_API zval* ZEND_FASTCALL zend_hash_index_add_empty_element(HashTable *ht, zend_ulong h)
{
-
zval dummy;
ZVAL_NULL(&dummy);
@@ -615,7 +614,6 @@ ZEND_API zval* ZEND_FASTCALL zend_hash_index_add_empty_element(HashTable *ht, ze
ZEND_API zval* ZEND_FASTCALL zend_hash_add_empty_element(HashTable *ht, zend_string *key)
{
-
zval dummy;
ZVAL_NULL(&dummy);
@@ -624,7 +622,6 @@ ZEND_API zval* ZEND_FASTCALL zend_hash_add_empty_element(HashTable *ht, zend_str
ZEND_API zval* ZEND_FASTCALL zend_hash_str_add_empty_element(HashTable *ht, const char *str, size_t len)
{
-
zval dummy;
ZVAL_NULL(&dummy);
@@ -1698,7 +1695,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
target->pDestructor = source->pDestructor;
if (source->nNumUsed == 0) {
- target->u.flags = (source->u.flags & ~(HASH_FLAG_INITIALIZED|HASH_FLAG_PERSISTENT)) | HASH_FLAG_APPLY_PROTECTION | HASH_FLAG_STATIC_KEYS;
+ target->u.flags = (source->u.flags & ~(HASH_FLAG_INITIALIZED|HASH_FLAG_PACKED|HASH_FLAG_PERSISTENT)) | HASH_FLAG_APPLY_PROTECTION | HASH_FLAG_STATIC_KEYS;
target->nTableMask = HT_MIN_MASK;
target->nNumUsed = 0;
target->nNumOfElements = 0;
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h
index dcac9c355c..e55ee9e61f 100644
--- a/Zend/zend_hash.h
+++ b/Zend/zend_hash.h
@@ -589,6 +589,15 @@ static zend_always_inline void *zend_hash_index_add_ptr(HashTable *ht, zend_ulon
return zv ? Z_PTR_P(zv) : NULL;
}
+static zend_always_inline void *zend_hash_index_add_new_ptr(HashTable *ht, zend_ulong h, void *pData)
+{
+ zval tmp, *zv;
+
+ ZVAL_PTR(&tmp, pData);
+ zv = zend_hash_index_add_new(ht, h, &tmp);
+ return zv ? Z_PTR_P(zv) : NULL;
+}
+
static zend_always_inline void *zend_hash_index_update_ptr(HashTable *ht, zend_ulong h, void *pData)
{
zval tmp, *zv;
@@ -845,8 +854,9 @@ static zend_always_inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht,
#define ZEND_HASH_APPLY_PROTECTION(ht) \
((ht)->u.flags & HASH_FLAG_APPLY_PROTECTION)
-#define ZEND_HASH_APPLY_SHIFT 8
-#define ZEND_HASH_GET_APPLY_COUNT(ht) ((ht)->u.flags >> ZEND_HASH_APPLY_SHIFT)
+#define ZEND_HASH_APPLY_SHIFT 8
+#define ZEND_HASH_APPLY_COUNT_MASK 0xff00
+#define ZEND_HASH_GET_APPLY_COUNT(ht) (((ht)->u.flags & ZEND_HASH_APPLY_COUNT_MASK) >> ZEND_HASH_APPLY_SHIFT)
#define ZEND_HASH_INC_APPLY_COUNT(ht) ((ht)->u.flags += (1 << ZEND_HASH_APPLY_SHIFT))
#define ZEND_HASH_DEC_APPLY_COUNT(ht) ((ht)->u.flags -= (1 << ZEND_HASH_APPLY_SHIFT))
@@ -877,7 +887,7 @@ static zend_always_inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht,
__fill_ht->nInternalPointer = 0; \
} while (0)
-static zend_always_inline void _zend_hash_append(HashTable *ht, zend_string *key, zval *zv)
+static zend_always_inline zval *_zend_hash_append(HashTable *ht, zend_string *key, zval *zv)
{
uint32_t idx = ht->nNumUsed++;
uint32_t nIndex;
@@ -896,9 +906,10 @@ static zend_always_inline void _zend_hash_append(HashTable *ht, zend_string *key
HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx);
ht->nNumUsed = idx + 1;
ht->nNumOfElements++;
+ return &p->val;
}
-static zend_always_inline void _zend_hash_append_ptr(HashTable *ht, zend_string *key, void *ptr)
+static zend_always_inline zval *_zend_hash_append_ptr(HashTable *ht, zend_string *key, void *ptr)
{
uint32_t idx = ht->nNumUsed++;
uint32_t nIndex;
@@ -917,6 +928,7 @@ static zend_always_inline void _zend_hash_append_ptr(HashTable *ht, zend_string
HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx);
ht->nNumUsed = idx + 1;
ht->nNumOfElements++;
+ return &p->val;
}
static zend_always_inline void _zend_hash_append_ind(HashTable *ht, zend_string *key, zval *ptr)
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index f32c55aaef..608af74353 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -1451,7 +1451,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce) /* {{{ */
* then check whether the property is already there
*/
flags = property_info->flags;
- if ((flags & ZEND_ACC_PPP_MASK) == ZEND_ACC_PUBLIC) {
+ if (flags & ZEND_ACC_PUBLIC) {
prop_name = zend_string_copy(property_info->name);
} else {
const char *pname;
diff --git a/Zend/zend_ini_scanner.c b/Zend/zend_ini_scanner.c
index 990a3733cd..6eb1ff716e 100644
--- a/Zend/zend_ini_scanner.c
+++ b/Zend/zend_ini_scanner.c
@@ -1937,7 +1937,7 @@ end_raw_value_chars:
}
/* Eat leading and trailing double quotes */
- if (yytext[0] == '"' && yytext[yyleng - 1] == '"') {
+ if (yyleng > 1 && yytext[0] == '"' && yytext[yyleng - 1] == '"') {
SCNG(yy_text)++;
yyleng = yyleng - 2;
} else if (sc) {
diff --git a/Zend/zend_ini_scanner.l b/Zend/zend_ini_scanner.l
index c82d79383f..8cc7266ebb 100644
--- a/Zend/zend_ini_scanner.l
+++ b/Zend/zend_ini_scanner.l
@@ -524,7 +524,7 @@ end_raw_value_chars:
}
/* Eat leading and trailing double quotes */
- if (yytext[0] == '"' && yytext[yyleng - 1] == '"') {
+ if (yyleng > 1 && yytext[0] == '"' && yytext[yyleng - 1] == '"') {
SCNG(yy_text)++;
yyleng = yyleng - 2;
} else if (sc) {
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index 2541c9f571..9612324eac 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -21,20 +21,13 @@
/* $Id$ */
-/*
- * LALR shift/reduce conflicts and how they are resolved:
- *
- * - 2 shift/reduce conflicts due to the dangling elseif/else ambiguity. Solved by shift.
- *
- */
-
-
#include "zend_compile.h"
#include "zend.h"
#include "zend_list.h"
#include "zend_globals.h"
#include "zend_API.h"
#include "zend_constants.h"
+#include "zend_language_scanner.h"
#define YYSIZE_T size_t
#define yytnamerr zend_yytnamerr
@@ -51,7 +44,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%}
%pure_parser
-%expect 2
+%expect 0
%code requires {
}
@@ -87,6 +80,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%right T_POW
%right '['
%nonassoc T_NEW T_CLONE
+%left T_NOELSE
%left T_ELSEIF
%left T_ELSE
%left T_ENDIF
@@ -243,8 +237,8 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%type <ast> absolute_trait_method_reference trait_method_reference property echo_expr
%type <ast> new_expr anonymous_class class_name class_name_reference simple_variable
%type <ast> internal_functions_in_yacc
-%type <ast> exit_expr scalar backticks_expr lexical_var function_call member_name
-%type <ast> variable_class_name dereferencable_scalar class_name_scalar constant dereferencable
+%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> top_statement_list use_declarations const_list inner_statement_list if_stmt
@@ -252,13 +246,14 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%type <ast> echo_expr_list unset_variables catch_list parameter_list class_statement_list
%type <ast> implements_list case_list if_stmt_without_else
%type <ast> non_empty_parameter_list argument_list non_empty_argument_list property_list
-%type <ast> class_const_list name_list trait_adaptations method_body non_empty_for_exprs
+%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> identifier
%type <num> returns_ref function is_reference is_variadic variable_modifiers
-%type <num> method_modifiers trait_modifiers non_empty_member_modifiers member_modifier
+%type <num> method_modifiers non_empty_member_modifiers member_modifier
%type <num> class_modifiers class_modifier use_type
%type <str> backup_doc_comment
@@ -269,6 +264,29 @@ start:
top_statement_list { CG(ast) = $1; }
;
+reserved_non_modifiers:
+ T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND
+ | T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE | T_ENDWHILE
+ | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH | T_FINALLY
+ | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO
+ | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT | T_BREAK
+ | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS
+;
+
+semi_reserved:
+ reserved_non_modifiers
+ | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC
+;
+
+identifier:
+ T_STRING { $$ = $1; }
+ | semi_reserved {
+ zval zv;
+ zend_lex_tstring(&zv);
+ $$ = zend_ast_create_zval(&zv);
+ }
+;
+
top_statement_list:
top_statement_list top_statement { $$ = zend_ast_list_add($1, $2); }
| /* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); }
@@ -561,7 +579,7 @@ if_stmt_without_else:
;
if_stmt:
- if_stmt_without_else { $$ = $1; }
+ if_stmt_without_else %prec T_NOELSE { $$ = $1; }
| if_stmt_without_else T_ELSE statement
{ $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_IF_ELEM, NULL, $3)); }
;
@@ -673,7 +691,7 @@ class_statement:
{ $$ = $2; RESET_DOC_COMMENT(); }
| T_USE name_list trait_adaptations
{ $$ = zend_ast_create(ZEND_AST_USE_TRAIT, $2, $3); }
- | method_modifiers function returns_ref T_STRING '(' parameter_list ')'
+ | method_modifiers function returns_ref identifier '(' parameter_list ')'
return_type backup_doc_comment method_body
{ $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1, $2, $9,
zend_ast_get_str($4), $6, NULL, $10, $8); }
@@ -708,28 +726,27 @@ trait_precedence:
;
trait_alias:
- trait_method_reference T_AS trait_modifiers T_STRING
+ trait_method_reference T_AS T_STRING
+ { $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, 0, $1, $3); }
+ | trait_method_reference T_AS reserved_non_modifiers
+ { zval zv; zend_lex_tstring(&zv); $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, 0, $1, zend_ast_create_zval(&zv)); }
+ | trait_method_reference T_AS member_modifier identifier
{ $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, $3, $1, $4); }
- | trait_method_reference T_AS member_modifier
+ | trait_method_reference T_AS member_modifier %prec '+'
{ $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, $3, $1, NULL); }
;
trait_method_reference:
- T_STRING
+ identifier
{ $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, NULL, $1); }
| absolute_trait_method_reference { $$ = $1; }
;
absolute_trait_method_reference:
- name T_PAAMAYIM_NEKUDOTAYIM T_STRING
+ name T_PAAMAYIM_NEKUDOTAYIM identifier
{ $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, $1, $3); }
;
-trait_modifiers:
- /* empty */ { $$ = 0; }
- | member_modifier { $$ = $1; }
-;
-
method_body:
';' /* abstract method */ { $$ = NULL; }
| '{' inner_statement_list '}' { $$ = $2; }
@@ -773,8 +790,12 @@ property:
;
class_const_list:
- class_const_list ',' const_decl { $$ = zend_ast_list_add($1, $3); }
- | const_decl { $$ = zend_ast_create_list(1, ZEND_AST_CLASS_CONST_DECL, $1); }
+ class_const_list ',' class_const_decl { $$ = zend_ast_list_add($1, $3); }
+ | class_const_decl { $$ = zend_ast_create_list(1, ZEND_AST_CLASS_CONST_DECL, $1); }
+;
+
+class_const_decl:
+ identifier '=' expr { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3); }
;
const_decl:
@@ -1028,15 +1049,14 @@ scalar:
| '"' encaps_list '"' { $$ = $2; }
| T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; }
| dereferencable_scalar { $$ = $1; }
- | class_name_scalar { $$ = $1; }
| constant { $$ = $1; }
;
constant:
name { $$ = zend_ast_create(ZEND_AST_CONST, $1); }
- | class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING
+ | class_name T_PAAMAYIM_NEKUDOTAYIM identifier
{ $$ = zend_ast_create(ZEND_AST_CLASS_CONST, $1, $3); }
- | variable_class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING
+ | variable_class_name T_PAAMAYIM_NEKUDOTAYIM identifier
{ $$ = zend_ast_create(ZEND_AST_CLASS_CONST, $1, $3); }
;
@@ -1080,7 +1100,7 @@ callable_variable:
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
| dereferencable '{' expr '}'
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
- | dereferencable T_OBJECT_OPERATOR member_name argument_list
+ | dereferencable T_OBJECT_OPERATOR property_name argument_list
{ $$ = zend_ast_create(ZEND_AST_METHOD_CALL, $1, $3, $4); }
| function_call { $$ = $1; }
;
@@ -1090,7 +1110,7 @@ variable:
{ $$ = $1; }
| static_member
{ $$ = $1; }
- | dereferencable T_OBJECT_OPERATOR member_name
+ | dereferencable T_OBJECT_OPERATOR property_name
{ $$ = zend_ast_create(ZEND_AST_PROP, $1, $3); }
;
@@ -1114,7 +1134,7 @@ new_variable:
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
| new_variable '{' expr '}'
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
- | new_variable T_OBJECT_OPERATOR member_name
+ | new_variable T_OBJECT_OPERATOR property_name
{ $$ = zend_ast_create(ZEND_AST_PROP, $1, $3); }
| class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable
{ $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); }
@@ -1123,7 +1143,13 @@ new_variable:
;
member_name:
- T_STRING { $$ = $1; }
+ identifier { $$ = $1; }
+ | '{' expr '}' { $$ = $2; }
+ | simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $1); }
+;
+
+property_name:
+ T_STRING { $$ = $1; }
| '{' expr '}' { $$ = $2; }
| simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $1); }
;
@@ -1226,11 +1252,6 @@ isset_variable:
expr { $$ = zend_ast_create(ZEND_AST_ISSET, $1); }
;
-class_name_scalar:
- class_name T_PAAMAYIM_NEKUDOTAYIM T_CLASS
- { $$ = zend_ast_create(ZEND_AST_RESOLVE_CLASS_NAME, $1); }
-;
-
%%
/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
diff --git a/Zend/zend_language_scanner.c b/Zend/zend_language_scanner.c
index e3b2de1a79..6813cf4db2 100644
--- a/Zend/zend_language_scanner.c
+++ b/Zend/zend_language_scanner.c
@@ -195,6 +195,7 @@ void shutdown_scanner(void)
zend_stack_destroy(&SCNG(state_stack));
zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1);
zend_ptr_stack_destroy(&SCNG(heredoc_label_stack));
+ SCNG(on_event) = NULL;
}
ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state)
@@ -225,6 +226,8 @@ ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state)
lex_state->output_filter = SCNG(output_filter);
lex_state->script_encoding = SCNG(script_encoding);
+ lex_state->on_event = SCNG(on_event);
+
lex_state->ast = CG(ast);
lex_state->ast_arena = CG(ast_arena);
}
@@ -262,6 +265,8 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state)
SCNG(output_filter) = lex_state->output_filter;
SCNG(script_encoding) = lex_state->script_encoding;
+ SCNG(on_event) = lex_state->on_event;
+
CG(ast) = lex_state->ast;
CG(ast_arena) = lex_state->ast_arena;
@@ -278,6 +283,13 @@ ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle)
}
}
+ZEND_API void zend_lex_tstring(zval *zv)
+{
+ if (SCNG(on_event)) SCNG(on_event)(ON_FEEDBACK, T_STRING, 0);
+
+ ZVAL_STRINGL(zv, (char*)SCNG(yy_text), SCNG(yy_leng));
+}
+
#define BOM_UTF32_BE "\x00\x00\xfe\xff"
#define BOM_UTF32_LE "\xff\xfe\x00\x00"
#define BOM_UTF16_BE "\xfe\xff"
@@ -1085,14 +1097,25 @@ static int zend_scan_escape_string(zval *zendlval, char *str, int len, char quot
return SUCCESS;
}
+static zend_always_inline int emit_token(int token, int token_line)
+{
+ if(SCNG(on_event)) SCNG(on_event)(ON_TOKEN, token, token_line);
+
+ return token;
+}
+
+#define RETURN_TOKEN(token) return emit_token(token, start_line);
int lex_scan(zval *zendlval)
{
+
+int start_line = CG(zend_lineno);
+
restart:
SCNG(yy_text) = YYCURSOR;
-#line 1096 "Zend/zend_language_scanner.c"
+#line 1119 "Zend/zend_language_scanner.c"
{
YYCTYPE yych;
unsigned int yyaccept = 0;
@@ -1146,10 +1169,10 @@ yyc_INITIAL:
yy3:
YYDEBUG(3, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1784 "Zend/zend_language_scanner.l"
+#line 1807 "Zend/zend_language_scanner.l"
{
if (YYCURSOR > YYLIMIT) {
- return 0;
+ RETURN_TOKEN(END);
}
inline_char_handler:
@@ -1189,9 +1212,9 @@ inline_char_handler:
ZVAL_STRINGL(zendlval, yytext, yyleng);
}
HANDLE_NEWLINES(yytext, yyleng);
- return T_INLINE_HTML;
+ RETURN_TOKEN(T_INLINE_HTML);
}
-#line 1195 "Zend/zend_language_scanner.c"
+#line 1218 "Zend/zend_language_scanner.c"
yy4:
YYDEBUG(4, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1209,27 +1232,27 @@ yy5:
yy6:
YYDEBUG(6, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1775 "Zend/zend_language_scanner.l"
+#line 1798 "Zend/zend_language_scanner.l"
{
if (CG(short_tags)) {
BEGIN(ST_IN_SCRIPTING);
- return T_OPEN_TAG;
+ RETURN_TOKEN(T_OPEN_TAG);
} else {
goto inline_char_handler;
}
}
-#line 1222 "Zend/zend_language_scanner.c"
+#line 1245 "Zend/zend_language_scanner.c"
yy7:
YYDEBUG(7, *YYCURSOR);
++YYCURSOR;
YYDEBUG(8, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1762 "Zend/zend_language_scanner.l"
+#line 1785 "Zend/zend_language_scanner.l"
{
BEGIN(ST_IN_SCRIPTING);
- return T_OPEN_TAG_WITH_ECHO;
+ RETURN_TOKEN(T_OPEN_TAG_WITH_ECHO);
}
-#line 1233 "Zend/zend_language_scanner.c"
+#line 1256 "Zend/zend_language_scanner.c"
yy9:
YYDEBUG(9, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1260,13 +1283,13 @@ yy13:
yy14:
YYDEBUG(14, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1768 "Zend/zend_language_scanner.l"
+#line 1791 "Zend/zend_language_scanner.l"
{
HANDLE_NEWLINE(yytext[yyleng-1]);
BEGIN(ST_IN_SCRIPTING);
- return T_OPEN_TAG;
+ RETURN_TOKEN(T_OPEN_TAG);
}
-#line 1270 "Zend/zend_language_scanner.c"
+#line 1293 "Zend/zend_language_scanner.c"
yy15:
YYDEBUG(15, *YYCURSOR);
++YYCURSOR;
@@ -1336,10 +1359,10 @@ yyc_ST_BACKQUOTE:
yy19:
YYDEBUG(19, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2198 "Zend/zend_language_scanner.l"
+#line 2221 "Zend/zend_language_scanner.l"
{
if (YYCURSOR > YYLIMIT) {
- return 0;
+ RETURN_TOKEN(END);
}
if (yytext[0] == '\\' && YYCURSOR < YYLIMIT) {
YYCURSOR++;
@@ -1375,11 +1398,11 @@ yy19:
yyleng = YYCURSOR - SCNG(yy_text);
if (zend_scan_escape_string(zendlval, yytext, yyleng, '`') == FAILURE) {
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
- return T_ENCAPSED_AND_WHITESPACE;
+ RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE);
}
-#line 1383 "Zend/zend_language_scanner.c"
+#line 1406 "Zend/zend_language_scanner.c"
yy20:
YYDEBUG(20, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1390,12 +1413,12 @@ yy21:
++YYCURSOR;
YYDEBUG(22, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2140 "Zend/zend_language_scanner.l"
+#line 2163 "Zend/zend_language_scanner.l"
{
BEGIN(ST_IN_SCRIPTING);
- return '`';
+ RETURN_TOKEN('`');
}
-#line 1399 "Zend/zend_language_scanner.c"
+#line 1422 "Zend/zend_language_scanner.c"
yy23:
YYDEBUG(23, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1405,14 +1428,14 @@ yy24:
++YYCURSOR;
YYDEBUG(25, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2127 "Zend/zend_language_scanner.l"
+#line 2150 "Zend/zend_language_scanner.l"
{
Z_LVAL_P(zendlval) = (zend_long) '{';
yy_push_state(ST_IN_SCRIPTING);
yyless(1);
- return T_CURLY_OPEN;
+ RETURN_TOKEN(T_CURLY_OPEN);
}
-#line 1416 "Zend/zend_language_scanner.c"
+#line 1439 "Zend/zend_language_scanner.c"
yy26:
YYDEBUG(26, *YYCURSOR);
yyaccept = 0;
@@ -1428,23 +1451,23 @@ yy26:
yy28:
YYDEBUG(28, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1849 "Zend/zend_language_scanner.l"
+#line 1872 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
-#line 1437 "Zend/zend_language_scanner.c"
+#line 1460 "Zend/zend_language_scanner.c"
yy29:
YYDEBUG(29, *YYCURSOR);
++YYCURSOR;
YYDEBUG(30, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1570 "Zend/zend_language_scanner.l"
+#line 1593 "Zend/zend_language_scanner.l"
{
yy_push_state(ST_LOOKING_FOR_VARNAME);
- return T_DOLLAR_OPEN_CURLY_BRACES;
+ RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES);
}
-#line 1448 "Zend/zend_language_scanner.c"
+#line 1471 "Zend/zend_language_scanner.c"
yy31:
YYDEBUG(31, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1458,14 +1481,14 @@ yy33:
++YYCURSOR;
YYDEBUG(34, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1842 "Zend/zend_language_scanner.l"
+#line 1865 "Zend/zend_language_scanner.l"
{
yyless(yyleng - 1);
yy_push_state(ST_VAR_OFFSET);
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
-#line 1469 "Zend/zend_language_scanner.c"
+#line 1492 "Zend/zend_language_scanner.c"
yy35:
YYDEBUG(35, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1483,14 +1506,14 @@ yy36:
++YYCURSOR;
YYDEBUG(37, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1833 "Zend/zend_language_scanner.l"
+#line 1856 "Zend/zend_language_scanner.l"
{
yyless(yyleng - 3);
yy_push_state(ST_LOOKING_FOR_PROPERTY);
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
-#line 1494 "Zend/zend_language_scanner.c"
+#line 1517 "Zend/zend_language_scanner.c"
}
/* *********************************** */
yyc_ST_DOUBLE_QUOTES:
@@ -1558,7 +1581,7 @@ yy40:
yy41:
YYDEBUG(41, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2146 "Zend/zend_language_scanner.l"
+#line 2169 "Zend/zend_language_scanner.l"
{
if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) {
YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1;
@@ -1568,7 +1591,7 @@ yy41:
}
if (YYCURSOR > YYLIMIT) {
- return 0;
+ RETURN_TOKEN(END);
}
if (yytext[0] == '\\' && YYCURSOR < YYLIMIT) {
YYCURSOR++;
@@ -1605,11 +1628,11 @@ double_quotes_scan_done:
yyleng = YYCURSOR - SCNG(yy_text);
if (zend_scan_escape_string(zendlval, yytext, yyleng, '"') == FAILURE) {
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
- return T_ENCAPSED_AND_WHITESPACE;
+ RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE);
}
-#line 1613 "Zend/zend_language_scanner.c"
+#line 1636 "Zend/zend_language_scanner.c"
yy42:
YYDEBUG(42, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1620,12 +1643,12 @@ yy43:
++YYCURSOR;
YYDEBUG(44, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2135 "Zend/zend_language_scanner.l"
+#line 2158 "Zend/zend_language_scanner.l"
{
BEGIN(ST_IN_SCRIPTING);
- return '"';
+ RETURN_TOKEN('"');
}
-#line 1629 "Zend/zend_language_scanner.c"
+#line 1652 "Zend/zend_language_scanner.c"
yy45:
YYDEBUG(45, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1635,14 +1658,14 @@ yy46:
++YYCURSOR;
YYDEBUG(47, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2127 "Zend/zend_language_scanner.l"
+#line 2150 "Zend/zend_language_scanner.l"
{
Z_LVAL_P(zendlval) = (zend_long) '{';
yy_push_state(ST_IN_SCRIPTING);
yyless(1);
- return T_CURLY_OPEN;
+ RETURN_TOKEN(T_CURLY_OPEN);
}
-#line 1646 "Zend/zend_language_scanner.c"
+#line 1669 "Zend/zend_language_scanner.c"
yy48:
YYDEBUG(48, *YYCURSOR);
yyaccept = 0;
@@ -1658,23 +1681,23 @@ yy48:
yy50:
YYDEBUG(50, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1849 "Zend/zend_language_scanner.l"
+#line 1872 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
-#line 1667 "Zend/zend_language_scanner.c"
+#line 1690 "Zend/zend_language_scanner.c"
yy51:
YYDEBUG(51, *YYCURSOR);
++YYCURSOR;
YYDEBUG(52, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1570 "Zend/zend_language_scanner.l"
+#line 1593 "Zend/zend_language_scanner.l"
{
yy_push_state(ST_LOOKING_FOR_VARNAME);
- return T_DOLLAR_OPEN_CURLY_BRACES;
+ RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES);
}
-#line 1678 "Zend/zend_language_scanner.c"
+#line 1701 "Zend/zend_language_scanner.c"
yy53:
YYDEBUG(53, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1688,14 +1711,14 @@ yy55:
++YYCURSOR;
YYDEBUG(56, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1842 "Zend/zend_language_scanner.l"
+#line 1865 "Zend/zend_language_scanner.l"
{
yyless(yyleng - 1);
yy_push_state(ST_VAR_OFFSET);
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
-#line 1699 "Zend/zend_language_scanner.c"
+#line 1722 "Zend/zend_language_scanner.c"
yy57:
YYDEBUG(57, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1713,14 +1736,14 @@ yy58:
++YYCURSOR;
YYDEBUG(59, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1833 "Zend/zend_language_scanner.l"
+#line 1856 "Zend/zend_language_scanner.l"
{
yyless(yyleng - 3);
yy_push_state(ST_LOOKING_FOR_PROPERTY);
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
-#line 1724 "Zend/zend_language_scanner.c"
+#line 1747 "Zend/zend_language_scanner.c"
}
/* *********************************** */
yyc_ST_END_HEREDOC:
@@ -1731,7 +1754,7 @@ yyc_ST_END_HEREDOC:
++YYCURSOR;
YYDEBUG(63, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2113 "Zend/zend_language_scanner.l"
+#line 2136 "Zend/zend_language_scanner.l"
{
zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack));
@@ -1742,9 +1765,9 @@ yyc_ST_END_HEREDOC:
efree(heredoc_label);
BEGIN(ST_IN_SCRIPTING);
- return T_END_HEREDOC;
+ RETURN_TOKEN(T_END_HEREDOC);
}
-#line 1748 "Zend/zend_language_scanner.c"
+#line 1771 "Zend/zend_language_scanner.c"
/* *********************************** */
yyc_ST_HEREDOC:
{
@@ -1806,14 +1829,14 @@ yy66:
yy67:
YYDEBUG(67, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2242 "Zend/zend_language_scanner.l"
+#line 2265 "Zend/zend_language_scanner.l"
{
int newline = 0;
zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
if (YYCURSOR > YYLIMIT) {
- return 0;
+ RETURN_TOKEN(END);
}
YYCURSOR--;
@@ -1877,11 +1900,11 @@ heredoc_scan_done:
yyleng = YYCURSOR - SCNG(yy_text);
if (zend_scan_escape_string(zendlval, yytext, yyleng - newline, 0) == FAILURE) {
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
- return T_ENCAPSED_AND_WHITESPACE;
+ RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE);
}
-#line 1885 "Zend/zend_language_scanner.c"
+#line 1908 "Zend/zend_language_scanner.c"
yy68:
YYDEBUG(68, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1896,14 +1919,14 @@ yy70:
++YYCURSOR;
YYDEBUG(71, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2127 "Zend/zend_language_scanner.l"
+#line 2150 "Zend/zend_language_scanner.l"
{
Z_LVAL_P(zendlval) = (zend_long) '{';
yy_push_state(ST_IN_SCRIPTING);
yyless(1);
- return T_CURLY_OPEN;
+ RETURN_TOKEN(T_CURLY_OPEN);
}
-#line 1907 "Zend/zend_language_scanner.c"
+#line 1930 "Zend/zend_language_scanner.c"
yy72:
YYDEBUG(72, *YYCURSOR);
yyaccept = 0;
@@ -1919,23 +1942,23 @@ yy72:
yy74:
YYDEBUG(74, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1849 "Zend/zend_language_scanner.l"
+#line 1872 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
-#line 1928 "Zend/zend_language_scanner.c"
+#line 1951 "Zend/zend_language_scanner.c"
yy75:
YYDEBUG(75, *YYCURSOR);
++YYCURSOR;
YYDEBUG(76, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1570 "Zend/zend_language_scanner.l"
+#line 1593 "Zend/zend_language_scanner.l"
{
yy_push_state(ST_LOOKING_FOR_VARNAME);
- return T_DOLLAR_OPEN_CURLY_BRACES;
+ RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES);
}
-#line 1939 "Zend/zend_language_scanner.c"
+#line 1962 "Zend/zend_language_scanner.c"
yy77:
YYDEBUG(77, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1949,14 +1972,14 @@ yy79:
++YYCURSOR;
YYDEBUG(80, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1842 "Zend/zend_language_scanner.l"
+#line 1865 "Zend/zend_language_scanner.l"
{
yyless(yyleng - 1);
yy_push_state(ST_VAR_OFFSET);
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
-#line 1960 "Zend/zend_language_scanner.c"
+#line 1983 "Zend/zend_language_scanner.c"
yy81:
YYDEBUG(81, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1974,14 +1997,14 @@ yy82:
++YYCURSOR;
YYDEBUG(83, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1833 "Zend/zend_language_scanner.l"
+#line 1856 "Zend/zend_language_scanner.l"
{
yyless(yyleng - 3);
yy_push_state(ST_LOOKING_FOR_PROPERTY);
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
-#line 1985 "Zend/zend_language_scanner.c"
+#line 2008 "Zend/zend_language_scanner.c"
}
/* *********************************** */
yyc_ST_IN_SCRIPTING:
@@ -2164,12 +2187,12 @@ yy86:
yy87:
YYDEBUG(87, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1872 "Zend/zend_language_scanner.l"
+#line 1895 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, yytext, yyleng);
- return T_STRING;
+ RETURN_TOKEN(T_STRING);
}
-#line 2173 "Zend/zend_language_scanner.c"
+#line 2196 "Zend/zend_language_scanner.c"
yy88:
YYDEBUG(88, *YYCURSOR);
yych = *++YYCURSOR;
@@ -2401,11 +2424,11 @@ yy101:
yy102:
YYDEBUG(102, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1559 "Zend/zend_language_scanner.l"
+#line 1582 "Zend/zend_language_scanner.l"
{
- return yytext[0];
+ RETURN_TOKEN(yytext[0]);
}
-#line 2409 "Zend/zend_language_scanner.c"
+#line 2432 "Zend/zend_language_scanner.c"
yy103:
YYDEBUG(103, *YYCURSOR);
++YYCURSOR;
@@ -2414,12 +2437,12 @@ yy103:
yy104:
YYDEBUG(104, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1274 "Zend/zend_language_scanner.l"
+#line 1297 "Zend/zend_language_scanner.l"
{
HANDLE_NEWLINES(yytext, yyleng);
- return T_WHITESPACE;
+ RETURN_TOKEN(T_WHITESPACE);
}
-#line 2423 "Zend/zend_language_scanner.c"
+#line 2446 "Zend/zend_language_scanner.c"
yy105:
YYDEBUG(105, *YYCURSOR);
yych = *++YYCURSOR;
@@ -2430,11 +2453,11 @@ yy106:
++YYCURSOR;
YYDEBUG(107, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1299 "Zend/zend_language_scanner.l"
+#line 1322 "Zend/zend_language_scanner.l"
{
- return T_NS_SEPARATOR;
+ RETURN_TOKEN(T_NS_SEPARATOR);
}
-#line 2438 "Zend/zend_language_scanner.c"
+#line 2461 "Zend/zend_language_scanner.c"
yy108:
YYDEBUG(108, *YYCURSOR);
yyaccept = 1;
@@ -2663,26 +2686,26 @@ yy131:
++YYCURSOR;
YYDEBUG(132, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1564 "Zend/zend_language_scanner.l"
+#line 1587 "Zend/zend_language_scanner.l"
{
yy_push_state(ST_IN_SCRIPTING);
- return '{';
+ RETURN_TOKEN('{');
}
-#line 2672 "Zend/zend_language_scanner.c"
+#line 2695 "Zend/zend_language_scanner.c"
yy133:
YYDEBUG(133, *YYCURSOR);
++YYCURSOR;
YYDEBUG(134, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1576 "Zend/zend_language_scanner.l"
+#line 1599 "Zend/zend_language_scanner.l"
{
RESET_DOC_COMMENT();
if (!zend_stack_is_empty(&SCNG(state_stack))) {
yy_pop_state();
}
- return '}';
+ RETURN_TOKEN('}');
}
-#line 2686 "Zend/zend_language_scanner.c"
+#line 2709 "Zend/zend_language_scanner.c"
yy135:
YYDEBUG(135, *YYCURSOR);
yyaccept = 2;
@@ -2710,7 +2733,7 @@ yy135:
yy136:
YYDEBUG(136, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1629 "Zend/zend_language_scanner.l"
+#line 1652 "Zend/zend_language_scanner.l"
{
char *end;
if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */
@@ -2721,7 +2744,7 @@ yy136:
*/
if (end != yytext + yyleng) {
zend_throw_exception(zend_get_parse_error(), "Invalid numeric literal", E_PARSE);
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
} else {
errno = 0;
@@ -2738,21 +2761,21 @@ yy136:
if (end != yytext + yyleng) {
zend_throw_exception(zend_get_parse_error(),
"Invalid numeric literal", E_PARSE);
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
ZEND_ASSERT(!errno);
- return T_DNUMBER;
+ RETURN_TOKEN(T_DNUMBER);
}
/* Also not an assert for the same reason */
if (end != yytext + yyleng) {
zend_throw_exception(zend_get_parse_error(), "Invalid numeric literal", E_PARSE);
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
}
ZEND_ASSERT(!errno);
- return T_LNUMBER;
+ RETURN_TOKEN(T_LNUMBER);
}
-#line 2756 "Zend/zend_language_scanner.c"
+#line 2779 "Zend/zend_language_scanner.c"
yy137:
YYDEBUG(137, *YYCURSOR);
yyaccept = 2;
@@ -2780,7 +2803,7 @@ yy139:
yy140:
YYDEBUG(140, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1878 "Zend/zend_language_scanner.l"
+#line 1901 "Zend/zend_language_scanner.l"
{
while (YYCURSOR < YYLIMIT) {
switch (*YYCURSOR++) {
@@ -2807,16 +2830,16 @@ yy140:
yyleng = YYCURSOR - SCNG(yy_text);
- return T_COMMENT;
+ RETURN_TOKEN(T_COMMENT);
}
-#line 2813 "Zend/zend_language_scanner.c"
+#line 2836 "Zend/zend_language_scanner.c"
yy141:
YYDEBUG(141, *YYCURSOR);
++YYCURSOR;
yy142:
YYDEBUG(142, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1946 "Zend/zend_language_scanner.l"
+#line 1969 "Zend/zend_language_scanner.l"
{
register char *s, *t;
char *end;
@@ -2839,7 +2862,7 @@ yy142:
* for ' (unrecognized by parser), instead of old flex fallback to "Unexpected character..."
* rule, which continued in ST_IN_SCRIPTING state after the quote */
ZVAL_NULL(zendlval);
- return T_ENCAPSED_AND_WHITESPACE;
+ RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE);
}
}
@@ -2882,16 +2905,16 @@ yy142:
SCNG(output_filter)((unsigned char **)&str, &sz, (unsigned char *)s, (size_t)Z_STRLEN_P(zendlval));
ZVAL_STRINGL(zendlval, str, sz);
}
- return T_CONSTANT_ENCAPSED_STRING;
+ RETURN_TOKEN(T_CONSTANT_ENCAPSED_STRING);
}
-#line 2888 "Zend/zend_language_scanner.c"
+#line 2911 "Zend/zend_language_scanner.c"
yy143:
YYDEBUG(143, *YYCURSOR);
++YYCURSOR;
yy144:
YYDEBUG(144, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2015 "Zend/zend_language_scanner.l"
+#line 2038 "Zend/zend_language_scanner.l"
{
int bprefix = (yytext[0] != '"') ? 1 : 0;
@@ -2900,9 +2923,9 @@ yy144:
case '"':
yyleng = YYCURSOR - SCNG(yy_text);
if (zend_scan_escape_string(zendlval, yytext+bprefix+1, yyleng-bprefix-2, '"') == FAILURE) {
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
- return T_CONSTANT_ENCAPSED_STRING;
+ RETURN_TOKEN(T_CONSTANT_ENCAPSED_STRING);
case '$':
if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
break;
@@ -2932,35 +2955,35 @@ yy144:
YYCURSOR = SCNG(yy_text) + yyleng;
BEGIN(ST_DOUBLE_QUOTES);
- return '"';
+ RETURN_TOKEN('"');
}
-#line 2938 "Zend/zend_language_scanner.c"
+#line 2961 "Zend/zend_language_scanner.c"
yy145:
YYDEBUG(145, *YYCURSOR);
++YYCURSOR;
YYDEBUG(146, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2107 "Zend/zend_language_scanner.l"
+#line 2130 "Zend/zend_language_scanner.l"
{
BEGIN(ST_BACKQUOTE);
- return '`';
+ RETURN_TOKEN('`');
}
-#line 2949 "Zend/zend_language_scanner.c"
+#line 2972 "Zend/zend_language_scanner.c"
yy147:
YYDEBUG(147, *YYCURSOR);
++YYCURSOR;
YYDEBUG(148, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2375 "Zend/zend_language_scanner.l"
+#line 2398 "Zend/zend_language_scanner.l"
{
if (YYCURSOR > YYLIMIT) {
- return 0;
+ RETURN_TOKEN(END);
}
zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
goto restart;
}
-#line 2964 "Zend/zend_language_scanner.c"
+#line 2987 "Zend/zend_language_scanner.c"
yy149:
YYDEBUG(149, *YYCURSOR);
++YYCURSOR;
@@ -2987,16 +3010,16 @@ yy151:
yy153:
YYDEBUG(153, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1720 "Zend/zend_language_scanner.l"
+#line 1743 "Zend/zend_language_scanner.l"
{
const char *end;
ZVAL_DOUBLE(zendlval, zend_strtod(yytext, &end));
/* errno isn't checked since we allow HUGE_VAL/INF overflow */
ZEND_ASSERT(end == yytext + yyleng);
- return T_DNUMBER;
+ RETURN_TOKEN(T_DNUMBER);
}
-#line 3000 "Zend/zend_language_scanner.c"
+#line 3023 "Zend/zend_language_scanner.c"
yy154:
YYDEBUG(154, *YYCURSOR);
yyaccept = 2;
@@ -3092,7 +3115,7 @@ yy163:
}
YYDEBUG(165, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1601 "Zend/zend_language_scanner.l"
+#line 1624 "Zend/zend_language_scanner.l"
{
char *bin = yytext + 2; /* Skip "0b" */
int len = yyleng - 2;
@@ -3112,15 +3135,15 @@ yy163:
ZVAL_LONG(zendlval, ZEND_STRTOL(bin, &end, 2));
ZEND_ASSERT(!errno && end == yytext + yyleng);
}
- return T_LNUMBER;
+ RETURN_TOKEN(T_LNUMBER);
} else {
ZVAL_DOUBLE(zendlval, zend_bin_strtod(bin, (const char **)&end));
/* errno isn't checked since we allow HUGE_VAL/INF overflow */
ZEND_ASSERT(end == yytext + yyleng);
- return T_DNUMBER;
+ RETURN_TOKEN(T_DNUMBER);
}
}
-#line 3124 "Zend/zend_language_scanner.c"
+#line 3147 "Zend/zend_language_scanner.c"
yy166:
YYDEBUG(166, *YYCURSOR);
++YYCURSOR;
@@ -3132,7 +3155,7 @@ yy166:
}
YYDEBUG(168, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1671 "Zend/zend_language_scanner.l"
+#line 1694 "Zend/zend_language_scanner.l"
{
char *hex = yytext + 2; /* Skip "0x" */
int len = yyleng - 2;
@@ -3152,15 +3175,15 @@ yy166:
ZVAL_LONG(zendlval, ZEND_STRTOL(hex, &end, 16));
ZEND_ASSERT(!errno && end == hex + len);
}
- return T_LNUMBER;
+ RETURN_TOKEN(T_LNUMBER);
} else {
ZVAL_DOUBLE(zendlval, zend_hex_strtod(hex, (const char **)&end));
/* errno isn't checked since we allow HUGE_VAL/INF overflow */
ZEND_ASSERT(end == hex + len);
- return T_DNUMBER;
+ RETURN_TOKEN(T_DNUMBER);
}
}
-#line 3164 "Zend/zend_language_scanner.c"
+#line 3187 "Zend/zend_language_scanner.c"
yy169:
YYDEBUG(169, *YYCURSOR);
++YYCURSOR;
@@ -3185,12 +3208,12 @@ yy169:
yy171:
YYDEBUG(171, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1849 "Zend/zend_language_scanner.l"
+#line 1872 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
-#line 3194 "Zend/zend_language_scanner.c"
+#line 3217 "Zend/zend_language_scanner.c"
yy172:
YYDEBUG(172, *YYCURSOR);
yych = *++YYCURSOR;
@@ -3204,11 +3227,11 @@ yy173:
}
YYDEBUG(174, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1547 "Zend/zend_language_scanner.l"
+#line 1570 "Zend/zend_language_scanner.l"
{
- return T_LOGICAL_XOR;
+ RETURN_TOKEN(T_LOGICAL_XOR);
}
-#line 3212 "Zend/zend_language_scanner.c"
+#line 3235 "Zend/zend_language_scanner.c"
yy175:
YYDEBUG(175, *YYCURSOR);
++YYCURSOR;
@@ -3217,71 +3240,71 @@ yy175:
}
YYDEBUG(176, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1539 "Zend/zend_language_scanner.l"
+#line 1562 "Zend/zend_language_scanner.l"
{
- return T_LOGICAL_OR;
+ RETURN_TOKEN(T_LOGICAL_OR);
}
-#line 3225 "Zend/zend_language_scanner.c"
+#line 3248 "Zend/zend_language_scanner.c"
yy177:
YYDEBUG(177, *YYCURSOR);
++YYCURSOR;
YYDEBUG(178, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1527 "Zend/zend_language_scanner.l"
+#line 1550 "Zend/zend_language_scanner.l"
{
- return T_XOR_EQUAL;
+ RETURN_TOKEN(T_XOR_EQUAL);
}
-#line 3235 "Zend/zend_language_scanner.c"
+#line 3258 "Zend/zend_language_scanner.c"
yy179:
YYDEBUG(179, *YYCURSOR);
++YYCURSOR;
YYDEBUG(180, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1531 "Zend/zend_language_scanner.l"
+#line 1554 "Zend/zend_language_scanner.l"
{
- return T_BOOLEAN_OR;
+ RETURN_TOKEN(T_BOOLEAN_OR);
}
-#line 3245 "Zend/zend_language_scanner.c"
+#line 3268 "Zend/zend_language_scanner.c"
yy181:
YYDEBUG(181, *YYCURSOR);
++YYCURSOR;
YYDEBUG(182, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1523 "Zend/zend_language_scanner.l"
+#line 1546 "Zend/zend_language_scanner.l"
{
- return T_OR_EQUAL;
+ RETURN_TOKEN(T_OR_EQUAL);
}
-#line 3255 "Zend/zend_language_scanner.c"
+#line 3278 "Zend/zend_language_scanner.c"
yy183:
YYDEBUG(183, *YYCURSOR);
++YYCURSOR;
YYDEBUG(184, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1535 "Zend/zend_language_scanner.l"
+#line 1558 "Zend/zend_language_scanner.l"
{
- return T_BOOLEAN_AND;
+ RETURN_TOKEN(T_BOOLEAN_AND);
}
-#line 3265 "Zend/zend_language_scanner.c"
+#line 3288 "Zend/zend_language_scanner.c"
yy185:
YYDEBUG(185, *YYCURSOR);
++YYCURSOR;
YYDEBUG(186, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1519 "Zend/zend_language_scanner.l"
+#line 1542 "Zend/zend_language_scanner.l"
{
- return T_AND_EQUAL;
+ RETURN_TOKEN(T_AND_EQUAL);
}
-#line 3275 "Zend/zend_language_scanner.c"
+#line 3298 "Zend/zend_language_scanner.c"
yy187:
YYDEBUG(187, *YYCURSOR);
++YYCURSOR;
YYDEBUG(188, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1507 "Zend/zend_language_scanner.l"
+#line 1530 "Zend/zend_language_scanner.l"
{
- return T_MOD_EQUAL;
+ RETURN_TOKEN(T_MOD_EQUAL);
}
-#line 3285 "Zend/zend_language_scanner.c"
+#line 3308 "Zend/zend_language_scanner.c"
yy189:
YYDEBUG(189, *YYCURSOR);
yyaccept = 4;
@@ -3290,7 +3313,7 @@ yy189:
yy190:
YYDEBUG(190, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1907 "Zend/zend_language_scanner.l"
+#line 1930 "Zend/zend_language_scanner.l"
{
int doc_com;
@@ -3318,12 +3341,12 @@ yy190:
if (doc_com) {
CG(doc_comment) = zend_string_init(yytext, yyleng, 0);
- return T_DOC_COMMENT;
+ RETURN_TOKEN(T_DOC_COMMENT);
}
- return T_COMMENT;
+ RETURN_TOKEN(T_COMMENT);
}
-#line 3327 "Zend/zend_language_scanner.c"
+#line 3350 "Zend/zend_language_scanner.c"
yy191:
YYDEBUG(191, *YYCURSOR);
yych = *++YYCURSOR;
@@ -3333,11 +3356,11 @@ yy192:
++YYCURSOR;
YYDEBUG(193, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1499 "Zend/zend_language_scanner.l"
+#line 1522 "Zend/zend_language_scanner.l"
{
- return T_DIV_EQUAL;
+ RETURN_TOKEN(T_DIV_EQUAL);
}
-#line 3341 "Zend/zend_language_scanner.c"
+#line 3364 "Zend/zend_language_scanner.c"
yy194:
YYDEBUG(194, *YYCURSOR);
yych = *++YYCURSOR;
@@ -3361,62 +3384,62 @@ yy197:
if ((yych = *YYCURSOR) == '=') goto yy201;
YYDEBUG(198, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1491 "Zend/zend_language_scanner.l"
+#line 1514 "Zend/zend_language_scanner.l"
{
- return T_POW;
+ RETURN_TOKEN(T_POW);
}
-#line 3369 "Zend/zend_language_scanner.c"
+#line 3392 "Zend/zend_language_scanner.c"
yy199:
YYDEBUG(199, *YYCURSOR);
++YYCURSOR;
YYDEBUG(200, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1487 "Zend/zend_language_scanner.l"
+#line 1510 "Zend/zend_language_scanner.l"
{
- return T_MUL_EQUAL;
+ RETURN_TOKEN(T_MUL_EQUAL);
}
-#line 3379 "Zend/zend_language_scanner.c"
+#line 3402 "Zend/zend_language_scanner.c"
yy201:
YYDEBUG(201, *YYCURSOR);
++YYCURSOR;
YYDEBUG(202, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1495 "Zend/zend_language_scanner.l"
+#line 1518 "Zend/zend_language_scanner.l"
{
- return T_POW_EQUAL;
+ RETURN_TOKEN(T_POW_EQUAL);
}
-#line 3389 "Zend/zend_language_scanner.c"
+#line 3412 "Zend/zend_language_scanner.c"
yy203:
YYDEBUG(203, *YYCURSOR);
++YYCURSOR;
if ((yych = *YYCURSOR) == '=') goto yy207;
YYDEBUG(204, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1555 "Zend/zend_language_scanner.l"
+#line 1578 "Zend/zend_language_scanner.l"
{
- return T_SR;
+ RETURN_TOKEN(T_SR);
}
-#line 3400 "Zend/zend_language_scanner.c"
+#line 3423 "Zend/zend_language_scanner.c"
yy205:
YYDEBUG(205, *YYCURSOR);
++YYCURSOR;
YYDEBUG(206, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1475 "Zend/zend_language_scanner.l"
+#line 1498 "Zend/zend_language_scanner.l"
{
- return T_IS_GREATER_OR_EQUAL;
+ RETURN_TOKEN(T_IS_GREATER_OR_EQUAL);
}
-#line 3410 "Zend/zend_language_scanner.c"
+#line 3433 "Zend/zend_language_scanner.c"
yy207:
YYDEBUG(207, *YYCURSOR);
++YYCURSOR;
YYDEBUG(208, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1515 "Zend/zend_language_scanner.l"
+#line 1538 "Zend/zend_language_scanner.l"
{
- return T_SR_EQUAL;
+ RETURN_TOKEN(T_SR_EQUAL);
}
-#line 3420 "Zend/zend_language_scanner.c"
+#line 3443 "Zend/zend_language_scanner.c"
yy209:
YYDEBUG(209, *YYCURSOR);
yyaccept = 5;
@@ -3427,53 +3450,53 @@ yy209:
yy210:
YYDEBUG(210, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1551 "Zend/zend_language_scanner.l"
+#line 1574 "Zend/zend_language_scanner.l"
{
- return T_SL;
+ RETURN_TOKEN(T_SL);
}
-#line 3435 "Zend/zend_language_scanner.c"
+#line 3458 "Zend/zend_language_scanner.c"
yy211:
YYDEBUG(211, *YYCURSOR);
++YYCURSOR;
if ((yych = *YYCURSOR) == '>') goto yy215;
YYDEBUG(212, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1471 "Zend/zend_language_scanner.l"
+#line 1494 "Zend/zend_language_scanner.l"
{
- return T_IS_SMALLER_OR_EQUAL;
+ RETURN_TOKEN(T_IS_SMALLER_OR_EQUAL);
}
-#line 3446 "Zend/zend_language_scanner.c"
+#line 3469 "Zend/zend_language_scanner.c"
yy213:
YYDEBUG(213, *YYCURSOR);
++YYCURSOR;
yy214:
YYDEBUG(214, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1463 "Zend/zend_language_scanner.l"
+#line 1486 "Zend/zend_language_scanner.l"
{
- return T_IS_NOT_EQUAL;
+ RETURN_TOKEN(T_IS_NOT_EQUAL);
}
-#line 3457 "Zend/zend_language_scanner.c"
+#line 3480 "Zend/zend_language_scanner.c"
yy215:
YYDEBUG(215, *YYCURSOR);
++YYCURSOR;
YYDEBUG(216, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1467 "Zend/zend_language_scanner.l"
+#line 1490 "Zend/zend_language_scanner.l"
{
- return T_SPACESHIP;
+ RETURN_TOKEN(T_SPACESHIP);
}
-#line 3467 "Zend/zend_language_scanner.c"
+#line 3490 "Zend/zend_language_scanner.c"
yy217:
YYDEBUG(217, *YYCURSOR);
++YYCURSOR;
YYDEBUG(218, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1511 "Zend/zend_language_scanner.l"
+#line 1534 "Zend/zend_language_scanner.l"
{
- return T_SL_EQUAL;
+ RETURN_TOKEN(T_SL_EQUAL);
}
-#line 3477 "Zend/zend_language_scanner.c"
+#line 3500 "Zend/zend_language_scanner.c"
yy219:
YYDEBUG(219, *YYCURSOR);
++YYCURSOR;
@@ -3578,7 +3601,7 @@ yy228:
yy229:
YYDEBUG(229, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2059 "Zend/zend_language_scanner.l"
+#line 2082 "Zend/zend_language_scanner.l"
{
char *s;
int bprefix = (yytext[0] != '<') ? 1 : 0;
@@ -3623,9 +3646,9 @@ yy229:
zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) heredoc_label);
- return T_START_HEREDOC;
+ RETURN_TOKEN(T_START_HEREDOC);
}
-#line 3629 "Zend/zend_language_scanner.c"
+#line 3652 "Zend/zend_language_scanner.c"
yy230:
YYDEBUG(230, *YYCURSOR);
yych = *++YYCURSOR;
@@ -3665,31 +3688,31 @@ yy233:
++YYCURSOR;
YYDEBUG(235, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1455 "Zend/zend_language_scanner.l"
+#line 1478 "Zend/zend_language_scanner.l"
{
- return T_IS_NOT_IDENTICAL;
+ RETURN_TOKEN(T_IS_NOT_IDENTICAL);
}
-#line 3673 "Zend/zend_language_scanner.c"
+#line 3696 "Zend/zend_language_scanner.c"
yy236:
YYDEBUG(236, *YYCURSOR);
++YYCURSOR;
YYDEBUG(237, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1479 "Zend/zend_language_scanner.l"
+#line 1502 "Zend/zend_language_scanner.l"
{
- return T_PLUS_EQUAL;
+ RETURN_TOKEN(T_PLUS_EQUAL);
}
-#line 3683 "Zend/zend_language_scanner.c"
+#line 3706 "Zend/zend_language_scanner.c"
yy238:
YYDEBUG(238, *YYCURSOR);
++YYCURSOR;
YYDEBUG(239, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1443 "Zend/zend_language_scanner.l"
+#line 1466 "Zend/zend_language_scanner.l"
{
- return T_INC;
+ RETURN_TOKEN(T_INC);
}
-#line 3693 "Zend/zend_language_scanner.c"
+#line 3716 "Zend/zend_language_scanner.c"
yy240:
YYDEBUG(240, *YYCURSOR);
yych = *++YYCURSOR;
@@ -3708,42 +3731,42 @@ yy242:
}
YYDEBUG(243, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1431 "Zend/zend_language_scanner.l"
+#line 1454 "Zend/zend_language_scanner.l"
{
- return T_LIST;
+ RETURN_TOKEN(T_LIST);
}
-#line 3716 "Zend/zend_language_scanner.c"
+#line 3739 "Zend/zend_language_scanner.c"
yy244:
YYDEBUG(244, *YYCURSOR);
++YYCURSOR;
if ((yych = *YYCURSOR) == '=') goto yy248;
YYDEBUG(245, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1459 "Zend/zend_language_scanner.l"
+#line 1482 "Zend/zend_language_scanner.l"
{
- return T_IS_EQUAL;
+ RETURN_TOKEN(T_IS_EQUAL);
}
-#line 3727 "Zend/zend_language_scanner.c"
+#line 3750 "Zend/zend_language_scanner.c"
yy246:
YYDEBUG(246, *YYCURSOR);
++YYCURSOR;
YYDEBUG(247, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1427 "Zend/zend_language_scanner.l"
+#line 1450 "Zend/zend_language_scanner.l"
{
- return T_DOUBLE_ARROW;
+ RETURN_TOKEN(T_DOUBLE_ARROW);
}
-#line 3737 "Zend/zend_language_scanner.c"
+#line 3760 "Zend/zend_language_scanner.c"
yy248:
YYDEBUG(248, *YYCURSOR);
++YYCURSOR;
YYDEBUG(249, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1451 "Zend/zend_language_scanner.l"
+#line 1474 "Zend/zend_language_scanner.l"
{
- return T_IS_IDENTICAL;
+ RETURN_TOKEN(T_IS_IDENTICAL);
}
-#line 3747 "Zend/zend_language_scanner.c"
+#line 3770 "Zend/zend_language_scanner.c"
yy250:
YYDEBUG(250, *YYCURSOR);
yych = *++YYCURSOR;
@@ -3873,11 +3896,11 @@ yy266:
}
YYDEBUG(269, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1757 "Zend/zend_language_scanner.l"
+#line 1780 "Zend/zend_language_scanner.l"
{
- return T_NS_C;
+ RETURN_TOKEN(T_NS_C);
}
-#line 3881 "Zend/zend_language_scanner.c"
+#line 3904 "Zend/zend_language_scanner.c"
yy270:
YYDEBUG(270, *YYCURSOR);
yych = *++YYCURSOR;
@@ -3897,11 +3920,11 @@ yy271:
}
YYDEBUG(274, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1753 "Zend/zend_language_scanner.l"
+#line 1776 "Zend/zend_language_scanner.l"
{
- return T_DIR;
+ RETURN_TOKEN(T_DIR);
}
-#line 3905 "Zend/zend_language_scanner.c"
+#line 3928 "Zend/zend_language_scanner.c"
yy275:
YYDEBUG(275, *YYCURSOR);
yych = *++YYCURSOR;
@@ -3926,11 +3949,11 @@ yy277:
}
YYDEBUG(280, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1745 "Zend/zend_language_scanner.l"
+#line 1768 "Zend/zend_language_scanner.l"
{
- return T_LINE;
+ RETURN_TOKEN(T_LINE);
}
-#line 3934 "Zend/zend_language_scanner.c"
+#line 3957 "Zend/zend_language_scanner.c"
yy281:
YYDEBUG(281, *YYCURSOR);
yych = *++YYCURSOR;
@@ -3965,11 +3988,11 @@ yy285:
}
YYDEBUG(288, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1741 "Zend/zend_language_scanner.l"
+#line 1764 "Zend/zend_language_scanner.l"
{
- return T_METHOD_C;
+ RETURN_TOKEN(T_METHOD_C);
}
-#line 3973 "Zend/zend_language_scanner.c"
+#line 3996 "Zend/zend_language_scanner.c"
yy289:
YYDEBUG(289, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4020,11 +4043,11 @@ yy296:
}
YYDEBUG(299, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1737 "Zend/zend_language_scanner.l"
+#line 1760 "Zend/zend_language_scanner.l"
{
- return T_FUNC_C;
+ RETURN_TOKEN(T_FUNC_C);
}
-#line 4028 "Zend/zend_language_scanner.c"
+#line 4051 "Zend/zend_language_scanner.c"
yy300:
YYDEBUG(300, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4044,11 +4067,11 @@ yy301:
}
YYDEBUG(304, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1749 "Zend/zend_language_scanner.l"
+#line 1772 "Zend/zend_language_scanner.l"
{
- return T_FILE;
+ RETURN_TOKEN(T_FILE);
}
-#line 4052 "Zend/zend_language_scanner.c"
+#line 4075 "Zend/zend_language_scanner.c"
yy305:
YYDEBUG(305, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4078,11 +4101,11 @@ yy308:
}
YYDEBUG(311, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1733 "Zend/zend_language_scanner.l"
+#line 1756 "Zend/zend_language_scanner.l"
{
- return T_TRAIT_C;
+ RETURN_TOKEN(T_TRAIT_C);
}
-#line 4086 "Zend/zend_language_scanner.c"
+#line 4109 "Zend/zend_language_scanner.c"
yy312:
YYDEBUG(312, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4112,11 +4135,11 @@ yy315:
}
YYDEBUG(318, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1729 "Zend/zend_language_scanner.l"
+#line 1752 "Zend/zend_language_scanner.l"
{
- return T_CLASS_C;
+ RETURN_TOKEN(T_CLASS_C);
}
-#line 4120 "Zend/zend_language_scanner.c"
+#line 4143 "Zend/zend_language_scanner.c"
yy319:
YYDEBUG(319, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4178,11 +4201,11 @@ yy330:
}
YYDEBUG(331, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1395 "Zend/zend_language_scanner.l"
+#line 1418 "Zend/zend_language_scanner.l"
{
- return T_HALT_COMPILER;
+ RETURN_TOKEN(T_HALT_COMPILER);
}
-#line 4186 "Zend/zend_language_scanner.c"
+#line 4209 "Zend/zend_language_scanner.c"
yy332:
YYDEBUG(332, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4202,11 +4225,11 @@ yy334:
}
YYDEBUG(335, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1375 "Zend/zend_language_scanner.l"
+#line 1398 "Zend/zend_language_scanner.l"
{
- return T_USE;
+ RETURN_TOKEN(T_USE);
}
-#line 4210 "Zend/zend_language_scanner.c"
+#line 4233 "Zend/zend_language_scanner.c"
yy336:
YYDEBUG(336, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4225,11 +4248,11 @@ yy338:
}
YYDEBUG(339, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1423 "Zend/zend_language_scanner.l"
+#line 1446 "Zend/zend_language_scanner.l"
{
- return T_UNSET;
+ RETURN_TOKEN(T_UNSET);
}
-#line 4233 "Zend/zend_language_scanner.c"
+#line 4256 "Zend/zend_language_scanner.c"
yy340:
YYDEBUG(340, *YYCURSOR);
++YYCURSOR;
@@ -4401,11 +4424,11 @@ yy355:
++YYCURSOR;
YYDEBUG(357, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1323 "Zend/zend_language_scanner.l"
+#line 1346 "Zend/zend_language_scanner.l"
{
- return T_INT_CAST;
+ RETURN_TOKEN(T_INT_CAST);
}
-#line 4409 "Zend/zend_language_scanner.c"
+#line 4432 "Zend/zend_language_scanner.c"
yy358:
YYDEBUG(358, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4449,11 +4472,11 @@ yy363:
++YYCURSOR;
YYDEBUG(366, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1327 "Zend/zend_language_scanner.l"
+#line 1350 "Zend/zend_language_scanner.l"
{
- return T_DOUBLE_CAST;
+ RETURN_TOKEN(T_DOUBLE_CAST);
}
-#line 4457 "Zend/zend_language_scanner.c"
+#line 4480 "Zend/zend_language_scanner.c"
yy367:
YYDEBUG(367, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4523,11 +4546,11 @@ yy377:
++YYCURSOR;
YYDEBUG(380, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1331 "Zend/zend_language_scanner.l"
+#line 1354 "Zend/zend_language_scanner.l"
{
- return T_STRING_CAST;
+ RETURN_TOKEN(T_STRING_CAST);
}
-#line 4531 "Zend/zend_language_scanner.c"
+#line 4554 "Zend/zend_language_scanner.c"
yy381:
YYDEBUG(381, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4560,11 +4583,11 @@ yy384:
++YYCURSOR;
YYDEBUG(387, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1335 "Zend/zend_language_scanner.l"
+#line 1358 "Zend/zend_language_scanner.l"
{
- return T_ARRAY_CAST;
+ RETURN_TOKEN(T_ARRAY_CAST);
}
-#line 4568 "Zend/zend_language_scanner.c"
+#line 4591 "Zend/zend_language_scanner.c"
yy388:
YYDEBUG(388, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4602,11 +4625,11 @@ yy392:
++YYCURSOR;
YYDEBUG(395, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1339 "Zend/zend_language_scanner.l"
+#line 1362 "Zend/zend_language_scanner.l"
{
- return T_OBJECT_CAST;
+ RETURN_TOKEN(T_OBJECT_CAST);
}
-#line 4610 "Zend/zend_language_scanner.c"
+#line 4633 "Zend/zend_language_scanner.c"
yy396:
YYDEBUG(396, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4647,11 +4670,11 @@ yy401:
++YYCURSOR;
YYDEBUG(403, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1343 "Zend/zend_language_scanner.l"
+#line 1366 "Zend/zend_language_scanner.l"
{
- return T_BOOL_CAST;
+ RETURN_TOKEN(T_BOOL_CAST);
}
-#line 4655 "Zend/zend_language_scanner.c"
+#line 4678 "Zend/zend_language_scanner.c"
yy404:
YYDEBUG(404, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4711,11 +4734,11 @@ yy412:
++YYCURSOR;
YYDEBUG(415, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1347 "Zend/zend_language_scanner.l"
+#line 1370 "Zend/zend_language_scanner.l"
{
- return T_UNSET_CAST;
+ RETURN_TOKEN(T_UNSET_CAST);
}
-#line 4719 "Zend/zend_language_scanner.c"
+#line 4742 "Zend/zend_language_scanner.c"
yy416:
YYDEBUG(416, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4729,11 +4752,11 @@ yy417:
}
YYDEBUG(418, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1319 "Zend/zend_language_scanner.l"
+#line 1342 "Zend/zend_language_scanner.l"
{
- return T_VAR;
+ RETURN_TOKEN(T_VAR);
}
-#line 4737 "Zend/zend_language_scanner.c"
+#line 4760 "Zend/zend_language_scanner.c"
yy419:
YYDEBUG(419, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4753,11 +4776,11 @@ yy421:
}
YYDEBUG(422, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1311 "Zend/zend_language_scanner.l"
+#line 1334 "Zend/zend_language_scanner.l"
{
- return T_NEW;
+ RETURN_TOKEN(T_NEW);
}
-#line 4761 "Zend/zend_language_scanner.c"
+#line 4784 "Zend/zend_language_scanner.c"
yy423:
YYDEBUG(423, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4796,11 +4819,11 @@ yy429:
}
YYDEBUG(430, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1371 "Zend/zend_language_scanner.l"
+#line 1394 "Zend/zend_language_scanner.l"
{
- return T_NAMESPACE;
+ RETURN_TOKEN(T_NAMESPACE);
}
-#line 4804 "Zend/zend_language_scanner.c"
+#line 4827 "Zend/zend_language_scanner.c"
yy431:
YYDEBUG(431, *YYCURSOR);
++YYCURSOR;
@@ -4809,22 +4832,22 @@ yy431:
yy432:
YYDEBUG(432, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1940 "Zend/zend_language_scanner.l"
+#line 1963 "Zend/zend_language_scanner.l"
{
BEGIN(INITIAL);
- return T_CLOSE_TAG; /* implicit ';' at php-end tag */
+ RETURN_TOKEN(T_CLOSE_TAG); /* implicit ';' at php-end tag */
}
-#line 4818 "Zend/zend_language_scanner.c"
+#line 4841 "Zend/zend_language_scanner.c"
yy433:
YYDEBUG(433, *YYCURSOR);
++YYCURSOR;
YYDEBUG(434, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1307 "Zend/zend_language_scanner.l"
+#line 1330 "Zend/zend_language_scanner.l"
{
- return T_COALESCE;
+ RETURN_TOKEN(T_COALESCE);
}
-#line 4828 "Zend/zend_language_scanner.c"
+#line 4851 "Zend/zend_language_scanner.c"
yy435:
YYDEBUG(435, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4855,11 +4878,11 @@ yy439:
++YYCURSOR;
YYDEBUG(440, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1503 "Zend/zend_language_scanner.l"
+#line 1526 "Zend/zend_language_scanner.l"
{
- return T_CONCAT_EQUAL;
+ RETURN_TOKEN(T_CONCAT_EQUAL);
}
-#line 4863 "Zend/zend_language_scanner.c"
+#line 4886 "Zend/zend_language_scanner.c"
yy441:
YYDEBUG(441, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4868,21 +4891,21 @@ yy441:
++YYCURSOR;
YYDEBUG(443, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1303 "Zend/zend_language_scanner.l"
+#line 1326 "Zend/zend_language_scanner.l"
{
- return T_ELLIPSIS;
+ RETURN_TOKEN(T_ELLIPSIS);
}
-#line 4876 "Zend/zend_language_scanner.c"
+#line 4899 "Zend/zend_language_scanner.c"
yy444:
YYDEBUG(444, *YYCURSOR);
++YYCURSOR;
YYDEBUG(445, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1295 "Zend/zend_language_scanner.l"
+#line 1318 "Zend/zend_language_scanner.l"
{
- return T_PAAMAYIM_NEKUDOTAYIM;
+ RETURN_TOKEN(T_PAAMAYIM_NEKUDOTAYIM);
}
-#line 4886 "Zend/zend_language_scanner.c"
+#line 4909 "Zend/zend_language_scanner.c"
yy446:
YYDEBUG(446, *YYCURSOR);
++YYCURSOR;
@@ -4904,32 +4927,32 @@ yy448:
++YYCURSOR;
YYDEBUG(449, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1483 "Zend/zend_language_scanner.l"
+#line 1506 "Zend/zend_language_scanner.l"
{
- return T_MINUS_EQUAL;
+ RETURN_TOKEN(T_MINUS_EQUAL);
}
-#line 4912 "Zend/zend_language_scanner.c"
+#line 4935 "Zend/zend_language_scanner.c"
yy450:
YYDEBUG(450, *YYCURSOR);
++YYCURSOR;
YYDEBUG(451, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1447 "Zend/zend_language_scanner.l"
+#line 1470 "Zend/zend_language_scanner.l"
{
- return T_DEC;
+ RETURN_TOKEN(T_DEC);
}
-#line 4922 "Zend/zend_language_scanner.c"
+#line 4945 "Zend/zend_language_scanner.c"
yy452:
YYDEBUG(452, *YYCURSOR);
++YYCURSOR;
YYDEBUG(453, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1269 "Zend/zend_language_scanner.l"
+#line 1292 "Zend/zend_language_scanner.l"
{
yy_push_state(ST_LOOKING_FOR_PROPERTY);
- return T_OBJECT_OPERATOR;
+ RETURN_TOKEN(T_OBJECT_OPERATOR);
}
-#line 4933 "Zend/zend_language_scanner.c"
+#line 4956 "Zend/zend_language_scanner.c"
yy454:
YYDEBUG(454, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4974,11 +4997,11 @@ yy459:
}
YYDEBUG(460, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1419 "Zend/zend_language_scanner.l"
+#line 1442 "Zend/zend_language_scanner.l"
{
- return T_PUBLIC;
+ RETURN_TOKEN(T_PUBLIC);
}
-#line 4982 "Zend/zend_language_scanner.c"
+#line 5005 "Zend/zend_language_scanner.c"
yy461:
YYDEBUG(461, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5033,11 +5056,11 @@ yy468:
}
YYDEBUG(469, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1415 "Zend/zend_language_scanner.l"
+#line 1438 "Zend/zend_language_scanner.l"
{
- return T_PROTECTED;
+ RETURN_TOKEN(T_PROTECTED);
}
-#line 5041 "Zend/zend_language_scanner.c"
+#line 5064 "Zend/zend_language_scanner.c"
yy470:
YYDEBUG(470, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5067,11 +5090,11 @@ yy474:
}
YYDEBUG(475, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1411 "Zend/zend_language_scanner.l"
+#line 1434 "Zend/zend_language_scanner.l"
{
- return T_PRIVATE;
+ RETURN_TOKEN(T_PRIVATE);
}
-#line 5075 "Zend/zend_language_scanner.c"
+#line 5098 "Zend/zend_language_scanner.c"
yy476:
YYDEBUG(476, *YYCURSOR);
++YYCURSOR;
@@ -5080,11 +5103,11 @@ yy476:
}
YYDEBUG(477, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1245 "Zend/zend_language_scanner.l"
+#line 1268 "Zend/zend_language_scanner.l"
{
- return T_PRINT;
+ RETURN_TOKEN(T_PRINT);
}
-#line 5088 "Zend/zend_language_scanner.c"
+#line 5111 "Zend/zend_language_scanner.c"
yy478:
YYDEBUG(478, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5109,11 +5132,11 @@ yy481:
}
YYDEBUG(482, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1237 "Zend/zend_language_scanner.l"
+#line 1260 "Zend/zend_language_scanner.l"
{
- return T_GOTO;
+ RETURN_TOKEN(T_GOTO);
}
-#line 5117 "Zend/zend_language_scanner.c"
+#line 5140 "Zend/zend_language_scanner.c"
yy483:
YYDEBUG(483, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5137,11 +5160,11 @@ yy486:
}
YYDEBUG(487, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1383 "Zend/zend_language_scanner.l"
+#line 1406 "Zend/zend_language_scanner.l"
{
- return T_GLOBAL;
+ RETURN_TOKEN(T_GLOBAL);
}
-#line 5145 "Zend/zend_language_scanner.c"
+#line 5168 "Zend/zend_language_scanner.c"
yy488:
YYDEBUG(488, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5178,11 +5201,11 @@ yy494:
}
YYDEBUG(495, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1229 "Zend/zend_language_scanner.l"
+#line 1252 "Zend/zend_language_scanner.l"
{
- return T_BREAK;
+ RETURN_TOKEN(T_BREAK);
}
-#line 5186 "Zend/zend_language_scanner.c"
+#line 5209 "Zend/zend_language_scanner.c"
yy496:
YYDEBUG(496, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5222,11 +5245,11 @@ yy502:
}
YYDEBUG(503, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1213 "Zend/zend_language_scanner.l"
+#line 1236 "Zend/zend_language_scanner.l"
{
- return T_SWITCH;
+ RETURN_TOKEN(T_SWITCH);
}
-#line 5230 "Zend/zend_language_scanner.c"
+#line 5253 "Zend/zend_language_scanner.c"
yy504:
YYDEBUG(504, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5250,11 +5273,11 @@ yy507:
}
YYDEBUG(508, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1399 "Zend/zend_language_scanner.l"
+#line 1422 "Zend/zend_language_scanner.l"
{
- return T_STATIC;
+ RETURN_TOKEN(T_STATIC);
}
-#line 5258 "Zend/zend_language_scanner.c"
+#line 5281 "Zend/zend_language_scanner.c"
yy509:
YYDEBUG(509, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5281,11 +5304,11 @@ yy512:
}
YYDEBUG(513, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1209 "Zend/zend_language_scanner.l"
+#line 1232 "Zend/zend_language_scanner.l"
{
- return T_AS;
+ RETURN_TOKEN(T_AS);
}
-#line 5289 "Zend/zend_language_scanner.c"
+#line 5312 "Zend/zend_language_scanner.c"
yy514:
YYDEBUG(514, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5304,11 +5327,11 @@ yy516:
}
YYDEBUG(517, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1435 "Zend/zend_language_scanner.l"
+#line 1458 "Zend/zend_language_scanner.l"
{
- return T_ARRAY;
+ RETURN_TOKEN(T_ARRAY);
}
-#line 5312 "Zend/zend_language_scanner.c"
+#line 5335 "Zend/zend_language_scanner.c"
yy518:
YYDEBUG(518, *YYCURSOR);
++YYCURSOR;
@@ -5317,11 +5340,11 @@ yy518:
}
YYDEBUG(519, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1543 "Zend/zend_language_scanner.l"
+#line 1566 "Zend/zend_language_scanner.l"
{
- return T_LOGICAL_AND;
+ RETURN_TOKEN(T_LOGICAL_AND);
}
-#line 5325 "Zend/zend_language_scanner.c"
+#line 5348 "Zend/zend_language_scanner.c"
yy520:
YYDEBUG(520, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5355,11 +5378,11 @@ yy525:
}
YYDEBUG(526, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1403 "Zend/zend_language_scanner.l"
+#line 1426 "Zend/zend_language_scanner.l"
{
- return T_ABSTRACT;
+ RETURN_TOKEN(T_ABSTRACT);
}
-#line 5363 "Zend/zend_language_scanner.c"
+#line 5386 "Zend/zend_language_scanner.c"
yy527:
YYDEBUG(527, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5383,11 +5406,11 @@ yy530:
}
YYDEBUG(531, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1169 "Zend/zend_language_scanner.l"
+#line 1192 "Zend/zend_language_scanner.l"
{
- return T_WHILE;
+ RETURN_TOKEN(T_WHILE);
}
-#line 5391 "Zend/zend_language_scanner.c"
+#line 5414 "Zend/zend_language_scanner.c"
yy532:
YYDEBUG(532, *YYCURSOR);
++YYCURSOR;
@@ -5396,11 +5419,11 @@ yy532:
}
YYDEBUG(533, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1153 "Zend/zend_language_scanner.l"
+#line 1176 "Zend/zend_language_scanner.l"
{
- return T_IF;
+ RETURN_TOKEN(T_IF);
}
-#line 5404 "Zend/zend_language_scanner.c"
+#line 5427 "Zend/zend_language_scanner.c"
yy534:
YYDEBUG(534, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5452,11 +5475,11 @@ yy539:
}
YYDEBUG(540, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1387 "Zend/zend_language_scanner.l"
+#line 1410 "Zend/zend_language_scanner.l"
{
- return T_ISSET;
+ RETURN_TOKEN(T_ISSET);
}
-#line 5460 "Zend/zend_language_scanner.c"
+#line 5483 "Zend/zend_language_scanner.c"
yy541:
YYDEBUG(541, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5510,11 +5533,11 @@ yy547:
yy548:
YYDEBUG(548, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1355 "Zend/zend_language_scanner.l"
+#line 1378 "Zend/zend_language_scanner.l"
{
- return T_INCLUDE;
+ RETURN_TOKEN(T_INCLUDE);
}
-#line 5518 "Zend/zend_language_scanner.c"
+#line 5541 "Zend/zend_language_scanner.c"
yy549:
YYDEBUG(549, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5543,11 +5566,11 @@ yy553:
}
YYDEBUG(554, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1359 "Zend/zend_language_scanner.l"
+#line 1382 "Zend/zend_language_scanner.l"
{
- return T_INCLUDE_ONCE;
+ RETURN_TOKEN(T_INCLUDE_ONCE);
}
-#line 5551 "Zend/zend_language_scanner.c"
+#line 5574 "Zend/zend_language_scanner.c"
yy555:
YYDEBUG(555, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5581,11 +5604,11 @@ yy560:
}
YYDEBUG(561, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1253 "Zend/zend_language_scanner.l"
+#line 1276 "Zend/zend_language_scanner.l"
{
- return T_INTERFACE;
+ RETURN_TOKEN(T_INTERFACE);
}
-#line 5589 "Zend/zend_language_scanner.c"
+#line 5612 "Zend/zend_language_scanner.c"
yy562:
YYDEBUG(562, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5635,11 +5658,11 @@ yy568:
}
YYDEBUG(569, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1379 "Zend/zend_language_scanner.l"
+#line 1402 "Zend/zend_language_scanner.l"
{
- return T_INSTEADOF;
+ RETURN_TOKEN(T_INSTEADOF);
}
-#line 5643 "Zend/zend_language_scanner.c"
+#line 5666 "Zend/zend_language_scanner.c"
yy570:
YYDEBUG(570, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5668,11 +5691,11 @@ yy574:
}
YYDEBUG(575, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1205 "Zend/zend_language_scanner.l"
+#line 1228 "Zend/zend_language_scanner.l"
{
- return T_INSTANCEOF;
+ RETURN_TOKEN(T_INSTANCEOF);
}
-#line 5676 "Zend/zend_language_scanner.c"
+#line 5699 "Zend/zend_language_scanner.c"
yy576:
YYDEBUG(576, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5716,11 +5739,11 @@ yy583:
}
YYDEBUG(584, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1265 "Zend/zend_language_scanner.l"
+#line 1288 "Zend/zend_language_scanner.l"
{
- return T_IMPLEMENTS;
+ RETURN_TOKEN(T_IMPLEMENTS);
}
-#line 5724 "Zend/zend_language_scanner.c"
+#line 5747 "Zend/zend_language_scanner.c"
yy585:
YYDEBUG(585, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5748,11 +5771,11 @@ yy586:
}
YYDEBUG(588, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1137 "Zend/zend_language_scanner.l"
+#line 1160 "Zend/zend_language_scanner.l"
{
- return T_TRY;
+ RETURN_TOKEN(T_TRY);
}
-#line 5756 "Zend/zend_language_scanner.c"
+#line 5779 "Zend/zend_language_scanner.c"
yy589:
YYDEBUG(589, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5771,11 +5794,11 @@ yy591:
}
YYDEBUG(592, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1257 "Zend/zend_language_scanner.l"
+#line 1280 "Zend/zend_language_scanner.l"
{
- return T_TRAIT;
+ RETURN_TOKEN(T_TRAIT);
}
-#line 5779 "Zend/zend_language_scanner.c"
+#line 5802 "Zend/zend_language_scanner.c"
yy593:
YYDEBUG(593, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5794,11 +5817,11 @@ yy595:
}
YYDEBUG(596, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1149 "Zend/zend_language_scanner.l"
+#line 1172 "Zend/zend_language_scanner.l"
{
- return T_THROW;
+ RETURN_TOKEN(T_THROW);
}
-#line 5802 "Zend/zend_language_scanner.c"
+#line 5825 "Zend/zend_language_scanner.c"
yy597:
YYDEBUG(597, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5831,11 +5854,11 @@ yy600:
yy601:
YYDEBUG(601, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1133 "Zend/zend_language_scanner.l"
+#line 1156 "Zend/zend_language_scanner.l"
{
- return T_YIELD;
+ RETURN_TOKEN(T_YIELD);
}
-#line 5839 "Zend/zend_language_scanner.c"
+#line 5862 "Zend/zend_language_scanner.c"
yy602:
YYDEBUG(602, *YYCURSOR);
++YYCURSOR;
@@ -5877,11 +5900,11 @@ yy607:
++YYCURSOR;
YYDEBUG(608, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1129 "Zend/zend_language_scanner.l"
+#line 1152 "Zend/zend_language_scanner.l"
{
- return T_YIELD_FROM;
+ RETURN_TOKEN(T_YIELD_FROM);
}
-#line 5885 "Zend/zend_language_scanner.c"
+#line 5908 "Zend/zend_language_scanner.c"
yy609:
YYDEBUG(609, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5942,11 +5965,11 @@ yy615:
yy616:
YYDEBUG(616, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1363 "Zend/zend_language_scanner.l"
+#line 1386 "Zend/zend_language_scanner.l"
{
- return T_REQUIRE;
+ RETURN_TOKEN(T_REQUIRE);
}
-#line 5950 "Zend/zend_language_scanner.c"
+#line 5973 "Zend/zend_language_scanner.c"
yy617:
YYDEBUG(617, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5975,11 +5998,11 @@ yy621:
}
YYDEBUG(622, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1367 "Zend/zend_language_scanner.l"
+#line 1390 "Zend/zend_language_scanner.l"
{
- return T_REQUIRE_ONCE;
+ RETURN_TOKEN(T_REQUIRE_ONCE);
}
-#line 5983 "Zend/zend_language_scanner.c"
+#line 6006 "Zend/zend_language_scanner.c"
yy623:
YYDEBUG(623, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5998,11 +6021,11 @@ yy625:
}
YYDEBUG(626, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1125 "Zend/zend_language_scanner.l"
+#line 1148 "Zend/zend_language_scanner.l"
{
- return T_RETURN;
+ RETURN_TOKEN(T_RETURN);
}
-#line 6006 "Zend/zend_language_scanner.c"
+#line 6029 "Zend/zend_language_scanner.c"
yy627:
YYDEBUG(627, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6092,11 +6115,11 @@ yy636:
}
YYDEBUG(637, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1233 "Zend/zend_language_scanner.l"
+#line 1256 "Zend/zend_language_scanner.l"
{
- return T_CONTINUE;
+ RETURN_TOKEN(T_CONTINUE);
}
-#line 6100 "Zend/zend_language_scanner.c"
+#line 6123 "Zend/zend_language_scanner.c"
yy638:
YYDEBUG(638, *YYCURSOR);
++YYCURSOR;
@@ -6105,11 +6128,11 @@ yy638:
}
YYDEBUG(639, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1121 "Zend/zend_language_scanner.l"
+#line 1144 "Zend/zend_language_scanner.l"
{
- return T_CONST;
+ RETURN_TOKEN(T_CONST);
}
-#line 6113 "Zend/zend_language_scanner.c"
+#line 6136 "Zend/zend_language_scanner.c"
yy640:
YYDEBUG(640, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6134,11 +6157,11 @@ yy643:
}
YYDEBUG(644, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1315 "Zend/zend_language_scanner.l"
+#line 1338 "Zend/zend_language_scanner.l"
{
- return T_CLONE;
+ RETURN_TOKEN(T_CLONE);
}
-#line 6142 "Zend/zend_language_scanner.c"
+#line 6165 "Zend/zend_language_scanner.c"
yy645:
YYDEBUG(645, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6152,11 +6175,11 @@ yy646:
}
YYDEBUG(647, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1249 "Zend/zend_language_scanner.l"
+#line 1272 "Zend/zend_language_scanner.l"
{
- return T_CLASS;
+ RETURN_TOKEN(T_CLASS);
}
-#line 6160 "Zend/zend_language_scanner.c"
+#line 6183 "Zend/zend_language_scanner.c"
yy648:
YYDEBUG(648, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6202,11 +6225,11 @@ yy655:
}
YYDEBUG(656, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1439 "Zend/zend_language_scanner.l"
+#line 1462 "Zend/zend_language_scanner.l"
{
- return T_CALLABLE;
+ RETURN_TOKEN(T_CALLABLE);
}
-#line 6210 "Zend/zend_language_scanner.c"
+#line 6233 "Zend/zend_language_scanner.c"
yy657:
YYDEBUG(657, *YYCURSOR);
++YYCURSOR;
@@ -6215,11 +6238,11 @@ yy657:
}
YYDEBUG(658, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1221 "Zend/zend_language_scanner.l"
+#line 1244 "Zend/zend_language_scanner.l"
{
- return T_CASE;
+ RETURN_TOKEN(T_CASE);
}
-#line 6223 "Zend/zend_language_scanner.c"
+#line 6246 "Zend/zend_language_scanner.c"
yy659:
YYDEBUG(659, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6233,11 +6256,11 @@ yy660:
}
YYDEBUG(661, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1141 "Zend/zend_language_scanner.l"
+#line 1164 "Zend/zend_language_scanner.l"
{
- return T_CATCH;
+ RETURN_TOKEN(T_CATCH);
}
-#line 6241 "Zend/zend_language_scanner.c"
+#line 6264 "Zend/zend_language_scanner.c"
yy662:
YYDEBUG(662, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6288,11 +6311,11 @@ yy670:
}
YYDEBUG(671, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1117 "Zend/zend_language_scanner.l"
+#line 1140 "Zend/zend_language_scanner.l"
{
- return T_FUNCTION;
+ RETURN_TOKEN(T_FUNCTION);
}
-#line 6296 "Zend/zend_language_scanner.c"
+#line 6319 "Zend/zend_language_scanner.c"
yy672:
YYDEBUG(672, *YYCURSOR);
++YYCURSOR;
@@ -6316,11 +6339,11 @@ yy672:
yy673:
YYDEBUG(673, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1181 "Zend/zend_language_scanner.l"
+#line 1204 "Zend/zend_language_scanner.l"
{
- return T_FOR;
+ RETURN_TOKEN(T_FOR);
}
-#line 6324 "Zend/zend_language_scanner.c"
+#line 6347 "Zend/zend_language_scanner.c"
yy674:
YYDEBUG(674, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6344,11 +6367,11 @@ yy677:
}
YYDEBUG(678, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1189 "Zend/zend_language_scanner.l"
+#line 1212 "Zend/zend_language_scanner.l"
{
- return T_FOREACH;
+ RETURN_TOKEN(T_FOREACH);
}
-#line 6352 "Zend/zend_language_scanner.c"
+#line 6375 "Zend/zend_language_scanner.c"
yy679:
YYDEBUG(679, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6382,11 +6405,11 @@ yy681:
yy682:
YYDEBUG(682, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1407 "Zend/zend_language_scanner.l"
+#line 1430 "Zend/zend_language_scanner.l"
{
- return T_FINAL;
+ RETURN_TOKEN(T_FINAL);
}
-#line 6390 "Zend/zend_language_scanner.c"
+#line 6413 "Zend/zend_language_scanner.c"
yy683:
YYDEBUG(683, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6400,11 +6423,11 @@ yy684:
}
YYDEBUG(685, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1145 "Zend/zend_language_scanner.l"
+#line 1168 "Zend/zend_language_scanner.l"
{
- return T_FINALLY;
+ RETURN_TOKEN(T_FINALLY);
}
-#line 6408 "Zend/zend_language_scanner.c"
+#line 6431 "Zend/zend_language_scanner.c"
yy686:
YYDEBUG(686, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6435,11 +6458,11 @@ yy688:
}
YYDEBUG(689, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1177 "Zend/zend_language_scanner.l"
+#line 1200 "Zend/zend_language_scanner.l"
{
- return T_DO;
+ RETURN_TOKEN(T_DO);
}
-#line 6443 "Zend/zend_language_scanner.c"
+#line 6466 "Zend/zend_language_scanner.c"
yy690:
YYDEBUG(690, *YYCURSOR);
++YYCURSOR;
@@ -6448,11 +6471,11 @@ yy690:
}
YYDEBUG(691, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1113 "Zend/zend_language_scanner.l"
+#line 1136 "Zend/zend_language_scanner.l"
{
- return T_EXIT;
+ RETURN_TOKEN(T_EXIT);
}
-#line 6456 "Zend/zend_language_scanner.c"
+#line 6479 "Zend/zend_language_scanner.c"
yy692:
YYDEBUG(692, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6487,11 +6510,11 @@ yy697:
}
YYDEBUG(698, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1225 "Zend/zend_language_scanner.l"
+#line 1248 "Zend/zend_language_scanner.l"
{
- return T_DEFAULT;
+ RETURN_TOKEN(T_DEFAULT);
}
-#line 6495 "Zend/zend_language_scanner.c"
+#line 6518 "Zend/zend_language_scanner.c"
yy699:
YYDEBUG(699, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6515,11 +6538,11 @@ yy702:
}
YYDEBUG(703, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1197 "Zend/zend_language_scanner.l"
+#line 1220 "Zend/zend_language_scanner.l"
{
- return T_DECLARE;
+ RETURN_TOKEN(T_DECLARE);
}
-#line 6523 "Zend/zend_language_scanner.c"
+#line 6546 "Zend/zend_language_scanner.c"
yy704:
YYDEBUG(704, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6599,11 +6622,11 @@ yy715:
}
YYDEBUG(716, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1261 "Zend/zend_language_scanner.l"
+#line 1284 "Zend/zend_language_scanner.l"
{
- return T_EXTENDS;
+ RETURN_TOKEN(T_EXTENDS);
}
-#line 6607 "Zend/zend_language_scanner.c"
+#line 6630 "Zend/zend_language_scanner.c"
yy717:
YYDEBUG(717, *YYCURSOR);
++YYCURSOR;
@@ -6612,11 +6635,11 @@ yy717:
}
YYDEBUG(718, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1109 "Zend/zend_language_scanner.l"
+#line 1132 "Zend/zend_language_scanner.l"
{
- return T_EXIT;
+ RETURN_TOKEN(T_EXIT);
}
-#line 6620 "Zend/zend_language_scanner.c"
+#line 6643 "Zend/zend_language_scanner.c"
yy719:
YYDEBUG(719, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6630,11 +6653,11 @@ yy720:
}
YYDEBUG(721, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1351 "Zend/zend_language_scanner.l"
+#line 1374 "Zend/zend_language_scanner.l"
{
- return T_EVAL;
+ RETURN_TOKEN(T_EVAL);
}
-#line 6638 "Zend/zend_language_scanner.c"
+#line 6661 "Zend/zend_language_scanner.c"
yy722:
YYDEBUG(722, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6704,11 +6727,11 @@ yy731:
}
YYDEBUG(732, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1173 "Zend/zend_language_scanner.l"
+#line 1196 "Zend/zend_language_scanner.l"
{
- return T_ENDWHILE;
+ RETURN_TOKEN(T_ENDWHILE);
}
-#line 6712 "Zend/zend_language_scanner.c"
+#line 6735 "Zend/zend_language_scanner.c"
yy733:
YYDEBUG(733, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6737,11 +6760,11 @@ yy737:
}
YYDEBUG(738, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1217 "Zend/zend_language_scanner.l"
+#line 1240 "Zend/zend_language_scanner.l"
{
- return T_ENDSWITCH;
+ RETURN_TOKEN(T_ENDSWITCH);
}
-#line 6745 "Zend/zend_language_scanner.c"
+#line 6768 "Zend/zend_language_scanner.c"
yy739:
YYDEBUG(739, *YYCURSOR);
++YYCURSOR;
@@ -6750,11 +6773,11 @@ yy739:
}
YYDEBUG(740, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1161 "Zend/zend_language_scanner.l"
+#line 1184 "Zend/zend_language_scanner.l"
{
- return T_ENDIF;
+ RETURN_TOKEN(T_ENDIF);
}
-#line 6758 "Zend/zend_language_scanner.c"
+#line 6781 "Zend/zend_language_scanner.c"
yy741:
YYDEBUG(741, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6783,11 +6806,11 @@ yy742:
yy743:
YYDEBUG(743, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1185 "Zend/zend_language_scanner.l"
+#line 1208 "Zend/zend_language_scanner.l"
{
- return T_ENDFOR;
+ RETURN_TOKEN(T_ENDFOR);
}
-#line 6791 "Zend/zend_language_scanner.c"
+#line 6814 "Zend/zend_language_scanner.c"
yy744:
YYDEBUG(744, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6811,11 +6834,11 @@ yy747:
}
YYDEBUG(748, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1193 "Zend/zend_language_scanner.l"
+#line 1216 "Zend/zend_language_scanner.l"
{
- return T_ENDFOREACH;
+ RETURN_TOKEN(T_ENDFOREACH);
}
-#line 6819 "Zend/zend_language_scanner.c"
+#line 6842 "Zend/zend_language_scanner.c"
yy749:
YYDEBUG(749, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6849,11 +6872,11 @@ yy754:
}
YYDEBUG(755, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1201 "Zend/zend_language_scanner.l"
+#line 1224 "Zend/zend_language_scanner.l"
{
- return T_ENDDECLARE;
+ RETURN_TOKEN(T_ENDDECLARE);
}
-#line 6857 "Zend/zend_language_scanner.c"
+#line 6880 "Zend/zend_language_scanner.c"
yy756:
YYDEBUG(756, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6872,11 +6895,11 @@ yy758:
}
YYDEBUG(759, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1391 "Zend/zend_language_scanner.l"
+#line 1414 "Zend/zend_language_scanner.l"
{
- return T_EMPTY;
+ RETURN_TOKEN(T_EMPTY);
}
-#line 6880 "Zend/zend_language_scanner.c"
+#line 6903 "Zend/zend_language_scanner.c"
yy760:
YYDEBUG(760, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6905,11 +6928,11 @@ yy761:
yy762:
YYDEBUG(762, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1165 "Zend/zend_language_scanner.l"
+#line 1188 "Zend/zend_language_scanner.l"
{
- return T_ELSE;
+ RETURN_TOKEN(T_ELSE);
}
-#line 6913 "Zend/zend_language_scanner.c"
+#line 6936 "Zend/zend_language_scanner.c"
yy763:
YYDEBUG(763, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6923,11 +6946,11 @@ yy764:
}
YYDEBUG(765, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1157 "Zend/zend_language_scanner.l"
+#line 1180 "Zend/zend_language_scanner.l"
{
- return T_ELSEIF;
+ RETURN_TOKEN(T_ELSEIF);
}
-#line 6931 "Zend/zend_language_scanner.c"
+#line 6954 "Zend/zend_language_scanner.c"
yy766:
YYDEBUG(766, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6941,11 +6964,11 @@ yy767:
}
YYDEBUG(768, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1241 "Zend/zend_language_scanner.l"
+#line 1264 "Zend/zend_language_scanner.l"
{
- return T_ECHO;
+ RETURN_TOKEN(T_ECHO);
}
-#line 6949 "Zend/zend_language_scanner.c"
+#line 6972 "Zend/zend_language_scanner.c"
}
/* *********************************** */
yyc_ST_LOOKING_FOR_PROPERTY:
@@ -7018,12 +7041,12 @@ yy771:
yy772:
YYDEBUG(772, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1274 "Zend/zend_language_scanner.l"
+#line 1297 "Zend/zend_language_scanner.l"
{
HANDLE_NEWLINES(yytext, yyleng);
- return T_WHITESPACE;
+ RETURN_TOKEN(T_WHITESPACE);
}
-#line 7027 "Zend/zend_language_scanner.c"
+#line 7050 "Zend/zend_language_scanner.c"
yy773:
YYDEBUG(773, *YYCURSOR);
++YYCURSOR;
@@ -7031,13 +7054,13 @@ yy773:
yy774:
YYDEBUG(774, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1289 "Zend/zend_language_scanner.l"
+#line 1312 "Zend/zend_language_scanner.l"
{
yyless(0);
yy_pop_state();
goto restart;
}
-#line 7041 "Zend/zend_language_scanner.c"
+#line 7064 "Zend/zend_language_scanner.c"
yy775:
YYDEBUG(775, *YYCURSOR);
++YYCURSOR;
@@ -7046,13 +7069,13 @@ yy775:
yy776:
YYDEBUG(776, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1283 "Zend/zend_language_scanner.l"
+#line 1306 "Zend/zend_language_scanner.l"
{
yy_pop_state();
zend_copy_value(zendlval, yytext, yyleng);
- return T_STRING;
+ RETURN_TOKEN(T_STRING);
}
-#line 7056 "Zend/zend_language_scanner.c"
+#line 7079 "Zend/zend_language_scanner.c"
yy777:
YYDEBUG(777, *YYCURSOR);
yych = *++YYCURSOR;
@@ -7073,11 +7096,11 @@ yy780:
++YYCURSOR;
YYDEBUG(781, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1279 "Zend/zend_language_scanner.l"
+#line 1302 "Zend/zend_language_scanner.l"
{
- return T_OBJECT_OPERATOR;
+ RETURN_TOKEN(T_OBJECT_OPERATOR);
}
-#line 7081 "Zend/zend_language_scanner.c"
+#line 7104 "Zend/zend_language_scanner.c"
yy782:
YYDEBUG(782, *YYCURSOR);
++YYCURSOR;
@@ -7162,14 +7185,14 @@ yy786:
yy787:
YYDEBUG(787, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1594 "Zend/zend_language_scanner.l"
+#line 1617 "Zend/zend_language_scanner.l"
{
yyless(0);
yy_pop_state();
yy_push_state(ST_IN_SCRIPTING);
goto restart;
}
-#line 7173 "Zend/zend_language_scanner.c"
+#line 7196 "Zend/zend_language_scanner.c"
yy788:
YYDEBUG(788, *YYCURSOR);
yych = *++YYCURSOR;
@@ -7194,15 +7217,15 @@ yy792:
++YYCURSOR;
YYDEBUG(793, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1585 "Zend/zend_language_scanner.l"
+#line 1608 "Zend/zend_language_scanner.l"
{
yyless(yyleng - 1);
zend_copy_value(zendlval, yytext, yyleng);
yy_pop_state();
yy_push_state(ST_IN_SCRIPTING);
- return T_STRING_VARNAME;
+ RETURN_TOKEN(T_STRING_VARNAME);
}
-#line 7206 "Zend/zend_language_scanner.c"
+#line 7229 "Zend/zend_language_scanner.c"
}
/* *********************************** */
yyc_ST_NOWDOC:
@@ -7213,14 +7236,14 @@ yyc_ST_NOWDOC:
++YYCURSOR;
YYDEBUG(797, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2318 "Zend/zend_language_scanner.l"
+#line 2341 "Zend/zend_language_scanner.l"
{
int newline = 0;
zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
if (YYCURSOR > YYLIMIT) {
- return 0;
+ RETURN_TOKEN(END);
}
YYCURSOR--;
@@ -7267,9 +7290,9 @@ nowdoc_scan_done:
zend_copy_value(zendlval, yytext, yyleng - newline);
HANDLE_NEWLINES(yytext, yyleng - newline);
- return T_ENCAPSED_AND_WHITESPACE;
+ RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE);
}
-#line 7273 "Zend/zend_language_scanner.c"
+#line 7296 "Zend/zend_language_scanner.c"
/* *********************************** */
yyc_ST_VAR_OFFSET:
{
@@ -7376,7 +7399,7 @@ yy800:
yy801:
YYDEBUG(801, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1699 "Zend/zend_language_scanner.l"
+#line 1722 "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;
@@ -7390,9 +7413,9 @@ yy801:
string:
ZVAL_STRINGL(zendlval, yytext, yyleng);
}
- return T_NUM_STRING;
+ RETURN_TOKEN(T_NUM_STRING);
}
-#line 7396 "Zend/zend_language_scanner.c"
+#line 7419 "Zend/zend_language_scanner.c"
yy802:
YYDEBUG(802, *YYCURSOR);
yych = *++YYCURSOR;
@@ -7412,23 +7435,23 @@ yy803:
yy804:
YYDEBUG(804, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1859 "Zend/zend_language_scanner.l"
+#line 1882 "Zend/zend_language_scanner.l"
{
/* Only '[' can be valid, but returning other tokens will allow a more explicit parse error */
- return yytext[0];
+ RETURN_TOKEN(yytext[0]);
}
-#line 7421 "Zend/zend_language_scanner.c"
+#line 7444 "Zend/zend_language_scanner.c"
yy805:
YYDEBUG(805, *YYCURSOR);
++YYCURSOR;
YYDEBUG(806, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1854 "Zend/zend_language_scanner.l"
+#line 1877 "Zend/zend_language_scanner.l"
{
yy_pop_state();
- return ']';
+ RETURN_TOKEN(']');
}
-#line 7432 "Zend/zend_language_scanner.c"
+#line 7455 "Zend/zend_language_scanner.c"
yy807:
YYDEBUG(807, *YYCURSOR);
yych = *++YYCURSOR;
@@ -7438,15 +7461,15 @@ yy808:
++YYCURSOR;
YYDEBUG(809, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1864 "Zend/zend_language_scanner.l"
+#line 1887 "Zend/zend_language_scanner.l"
{
/* Invalid rule to return a more explicit parse error with proper line number */
yyless(0);
yy_pop_state();
ZVAL_NULL(zendlval);
- return T_ENCAPSED_AND_WHITESPACE;
+ RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE);
}
-#line 7450 "Zend/zend_language_scanner.c"
+#line 7473 "Zend/zend_language_scanner.c"
yy810:
YYDEBUG(810, *YYCURSOR);
++YYCURSOR;
@@ -7455,27 +7478,27 @@ yy810:
yy811:
YYDEBUG(811, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1872 "Zend/zend_language_scanner.l"
+#line 1895 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, yytext, yyleng);
- return T_STRING;
+ RETURN_TOKEN(T_STRING);
}
-#line 7464 "Zend/zend_language_scanner.c"
+#line 7487 "Zend/zend_language_scanner.c"
yy812:
YYDEBUG(812, *YYCURSOR);
++YYCURSOR;
YYDEBUG(813, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2375 "Zend/zend_language_scanner.l"
+#line 2398 "Zend/zend_language_scanner.l"
{
if (YYCURSOR > YYLIMIT) {
- return 0;
+ RETURN_TOKEN(END);
}
zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
goto restart;
}
-#line 7479 "Zend/zend_language_scanner.c"
+#line 7502 "Zend/zend_language_scanner.c"
yy814:
YYDEBUG(814, *YYCURSOR);
++YYCURSOR;
@@ -7511,12 +7534,12 @@ yy816:
yy818:
YYDEBUG(818, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1849 "Zend/zend_language_scanner.l"
+#line 1872 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
-#line 7520 "Zend/zend_language_scanner.c"
+#line 7543 "Zend/zend_language_scanner.c"
yy819:
YYDEBUG(819, *YYCURSOR);
++YYCURSOR;
@@ -7556,12 +7579,12 @@ yy824:
yy826:
YYDEBUG(826, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1715 "Zend/zend_language_scanner.l"
+#line 1738 "Zend/zend_language_scanner.l"
{ /* Offset must be treated as a string */
ZVAL_STRINGL(zendlval, yytext, yyleng);
- return T_NUM_STRING;
+ RETURN_TOKEN(T_NUM_STRING);
}
-#line 7565 "Zend/zend_language_scanner.c"
+#line 7588 "Zend/zend_language_scanner.c"
yy827:
YYDEBUG(827, *YYCURSOR);
++YYCURSOR;
@@ -7584,6 +7607,6 @@ yy829:
goto yy826;
}
}
-#line 2384 "Zend/zend_language_scanner.l"
+#line 2407 "Zend/zend_language_scanner.l"
}
diff --git a/Zend/zend_language_scanner.h b/Zend/zend_language_scanner.h
index c82b3069c5..3b75ff8cc4 100644
--- a/Zend/zend_language_scanner.h
+++ b/Zend/zend_language_scanner.h
@@ -50,6 +50,9 @@ typedef struct _zend_lex_state {
zend_encoding_filter output_filter;
const zend_encoding *script_encoding;
+ /* hooks */
+ void (* on_event)(zend_php_scanner_event event, int token, int line);
+
zend_ast *ast;
zend_arena *ast_arena;
} zend_lex_state;
@@ -66,6 +69,7 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state);
ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename);
ZEND_API void zend_multibyte_yyinput_again(zend_encoding_filter old_input_filter, const zend_encoding *old_encoding);
ZEND_API int zend_multibyte_set_filter(const zend_encoding *onetime_encoding);
+ZEND_API void zend_lex_tstring(zval *zv);
END_EXTERN_C()
diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l
index 1204287ad9..01c489cbe4 100644
--- a/Zend/zend_language_scanner.l
+++ b/Zend/zend_language_scanner.l
@@ -193,6 +193,7 @@ void shutdown_scanner(void)
zend_stack_destroy(&SCNG(state_stack));
zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1);
zend_ptr_stack_destroy(&SCNG(heredoc_label_stack));
+ SCNG(on_event) = NULL;
}
ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state)
@@ -223,6 +224,8 @@ ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state)
lex_state->output_filter = SCNG(output_filter);
lex_state->script_encoding = SCNG(script_encoding);
+ lex_state->on_event = SCNG(on_event);
+
lex_state->ast = CG(ast);
lex_state->ast_arena = CG(ast_arena);
}
@@ -260,6 +263,8 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state)
SCNG(output_filter) = lex_state->output_filter;
SCNG(script_encoding) = lex_state->script_encoding;
+ SCNG(on_event) = lex_state->on_event;
+
CG(ast) = lex_state->ast;
CG(ast_arena) = lex_state->ast_arena;
@@ -276,6 +281,13 @@ ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle)
}
}
+ZEND_API void zend_lex_tstring(zval *zv)
+{
+ if (SCNG(on_event)) SCNG(on_event)(ON_FEEDBACK, T_STRING, 0);
+
+ ZVAL_STRINGL(zv, (char*)SCNG(yy_text), SCNG(yy_leng));
+}
+
#define BOM_UTF32_BE "\x00\x00\xfe\xff"
#define BOM_UTF32_LE "\xff\xfe\x00\x00"
#define BOM_UTF16_BE "\xfe\xff"
@@ -1083,9 +1095,20 @@ static int zend_scan_escape_string(zval *zendlval, char *str, int len, char quot
return SUCCESS;
}
+static zend_always_inline int emit_token(int token, int token_line)
+{
+ if(SCNG(on_event)) SCNG(on_event)(ON_TOKEN, token, token_line);
+
+ return token;
+}
+
+#define RETURN_TOKEN(token) return emit_token(token, start_line);
int lex_scan(zval *zendlval)
{
+
+int start_line = CG(zend_lineno);
+
restart:
SCNG(yy_text) = YYCURSOR;
@@ -1107,183 +1130,183 @@ NEWLINE ("\r"|"\n"|"\r\n")
<!*> := yyleng = YYCURSOR - SCNG(yy_text);
<ST_IN_SCRIPTING>"exit" {
- return T_EXIT;
+ RETURN_TOKEN(T_EXIT);
}
<ST_IN_SCRIPTING>"die" {
- return T_EXIT;
+ RETURN_TOKEN(T_EXIT);
}
<ST_IN_SCRIPTING>"function" {
- return T_FUNCTION;
+ RETURN_TOKEN(T_FUNCTION);
}
<ST_IN_SCRIPTING>"const" {
- return T_CONST;
+ RETURN_TOKEN(T_CONST);
}
<ST_IN_SCRIPTING>"return" {
- return T_RETURN;
+ RETURN_TOKEN(T_RETURN);
}
<ST_IN_SCRIPTING>"yield"{WHITESPACE}"from" {
- return T_YIELD_FROM;
+ RETURN_TOKEN(T_YIELD_FROM);
}
<ST_IN_SCRIPTING>"yield" {
- return T_YIELD;
+ RETURN_TOKEN(T_YIELD);
}
<ST_IN_SCRIPTING>"try" {
- return T_TRY;
+ RETURN_TOKEN(T_TRY);
}
<ST_IN_SCRIPTING>"catch" {
- return T_CATCH;
+ RETURN_TOKEN(T_CATCH);
}
<ST_IN_SCRIPTING>"finally" {
- return T_FINALLY;
+ RETURN_TOKEN(T_FINALLY);
}
<ST_IN_SCRIPTING>"throw" {
- return T_THROW;
+ RETURN_TOKEN(T_THROW);
}
<ST_IN_SCRIPTING>"if" {
- return T_IF;
+ RETURN_TOKEN(T_IF);
}
<ST_IN_SCRIPTING>"elseif" {
- return T_ELSEIF;
+ RETURN_TOKEN(T_ELSEIF);
}
<ST_IN_SCRIPTING>"endif" {
- return T_ENDIF;
+ RETURN_TOKEN(T_ENDIF);
}
<ST_IN_SCRIPTING>"else" {
- return T_ELSE;
+ RETURN_TOKEN(T_ELSE);
}
<ST_IN_SCRIPTING>"while" {
- return T_WHILE;
+ RETURN_TOKEN(T_WHILE);
}
<ST_IN_SCRIPTING>"endwhile" {
- return T_ENDWHILE;
+ RETURN_TOKEN(T_ENDWHILE);
}
<ST_IN_SCRIPTING>"do" {
- return T_DO;
+ RETURN_TOKEN(T_DO);
}
<ST_IN_SCRIPTING>"for" {
- return T_FOR;
+ RETURN_TOKEN(T_FOR);
}
<ST_IN_SCRIPTING>"endfor" {
- return T_ENDFOR;
+ RETURN_TOKEN(T_ENDFOR);
}
<ST_IN_SCRIPTING>"foreach" {
- return T_FOREACH;
+ RETURN_TOKEN(T_FOREACH);
}
<ST_IN_SCRIPTING>"endforeach" {
- return T_ENDFOREACH;
+ RETURN_TOKEN(T_ENDFOREACH);
}
<ST_IN_SCRIPTING>"declare" {
- return T_DECLARE;
+ RETURN_TOKEN(T_DECLARE);
}
<ST_IN_SCRIPTING>"enddeclare" {
- return T_ENDDECLARE;
+ RETURN_TOKEN(T_ENDDECLARE);
}
<ST_IN_SCRIPTING>"instanceof" {
- return T_INSTANCEOF;
+ RETURN_TOKEN(T_INSTANCEOF);
}
<ST_IN_SCRIPTING>"as" {
- return T_AS;
+ RETURN_TOKEN(T_AS);
}
<ST_IN_SCRIPTING>"switch" {
- return T_SWITCH;
+ RETURN_TOKEN(T_SWITCH);
}
<ST_IN_SCRIPTING>"endswitch" {
- return T_ENDSWITCH;
+ RETURN_TOKEN(T_ENDSWITCH);
}
<ST_IN_SCRIPTING>"case" {
- return T_CASE;
+ RETURN_TOKEN(T_CASE);
}
<ST_IN_SCRIPTING>"default" {
- return T_DEFAULT;
+ RETURN_TOKEN(T_DEFAULT);
}
<ST_IN_SCRIPTING>"break" {
- return T_BREAK;
+ RETURN_TOKEN(T_BREAK);
}
<ST_IN_SCRIPTING>"continue" {
- return T_CONTINUE;
+ RETURN_TOKEN(T_CONTINUE);
}
<ST_IN_SCRIPTING>"goto" {
- return T_GOTO;
+ RETURN_TOKEN(T_GOTO);
}
<ST_IN_SCRIPTING>"echo" {
- return T_ECHO;
+ RETURN_TOKEN(T_ECHO);
}
<ST_IN_SCRIPTING>"print" {
- return T_PRINT;
+ RETURN_TOKEN(T_PRINT);
}
<ST_IN_SCRIPTING>"class" {
- return T_CLASS;
+ RETURN_TOKEN(T_CLASS);
}
<ST_IN_SCRIPTING>"interface" {
- return T_INTERFACE;
+ RETURN_TOKEN(T_INTERFACE);
}
<ST_IN_SCRIPTING>"trait" {
- return T_TRAIT;
+ RETURN_TOKEN(T_TRAIT);
}
<ST_IN_SCRIPTING>"extends" {
- return T_EXTENDS;
+ RETURN_TOKEN(T_EXTENDS);
}
<ST_IN_SCRIPTING>"implements" {
- return T_IMPLEMENTS;
+ RETURN_TOKEN(T_IMPLEMENTS);
}
<ST_IN_SCRIPTING>"->" {
yy_push_state(ST_LOOKING_FOR_PROPERTY);
- return T_OBJECT_OPERATOR;
+ RETURN_TOKEN(T_OBJECT_OPERATOR);
}
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY>{WHITESPACE}+ {
HANDLE_NEWLINES(yytext, yyleng);
- return T_WHITESPACE;
+ RETURN_TOKEN(T_WHITESPACE);
}
<ST_LOOKING_FOR_PROPERTY>"->" {
- return T_OBJECT_OPERATOR;
+ RETURN_TOKEN(T_OBJECT_OPERATOR);
}
<ST_LOOKING_FOR_PROPERTY>{LABEL} {
yy_pop_state();
zend_copy_value(zendlval, yytext, yyleng);
- return T_STRING;
+ RETURN_TOKEN(T_STRING);
}
<ST_LOOKING_FOR_PROPERTY>{ANY_CHAR} {
@@ -1293,283 +1316,283 @@ NEWLINE ("\r"|"\n"|"\r\n")
}
<ST_IN_SCRIPTING>"::" {
- return T_PAAMAYIM_NEKUDOTAYIM;
+ RETURN_TOKEN(T_PAAMAYIM_NEKUDOTAYIM);
}
<ST_IN_SCRIPTING>"\\" {
- return T_NS_SEPARATOR;
+ RETURN_TOKEN(T_NS_SEPARATOR);
}
<ST_IN_SCRIPTING>"..." {
- return T_ELLIPSIS;
+ RETURN_TOKEN(T_ELLIPSIS);
}
<ST_IN_SCRIPTING>"??" {
- return T_COALESCE;
+ RETURN_TOKEN(T_COALESCE);
}
<ST_IN_SCRIPTING>"new" {
- return T_NEW;
+ RETURN_TOKEN(T_NEW);
}
<ST_IN_SCRIPTING>"clone" {
- return T_CLONE;
+ RETURN_TOKEN(T_CLONE);
}
<ST_IN_SCRIPTING>"var" {
- return T_VAR;
+ RETURN_TOKEN(T_VAR);
}
<ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("int"|"integer"){TABS_AND_SPACES}")" {
- return T_INT_CAST;
+ RETURN_TOKEN(T_INT_CAST);
}
<ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("real"|"double"|"float"){TABS_AND_SPACES}")" {
- return T_DOUBLE_CAST;
+ RETURN_TOKEN(T_DOUBLE_CAST);
}
<ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("string"|"binary"){TABS_AND_SPACES}")" {
- return T_STRING_CAST;
+ RETURN_TOKEN(T_STRING_CAST);
}
<ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"array"{TABS_AND_SPACES}")" {
- return T_ARRAY_CAST;
+ RETURN_TOKEN(T_ARRAY_CAST);
}
<ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"object"{TABS_AND_SPACES}")" {
- return T_OBJECT_CAST;
+ RETURN_TOKEN(T_OBJECT_CAST);
}
<ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("bool"|"boolean"){TABS_AND_SPACES}")" {
- return T_BOOL_CAST;
+ RETURN_TOKEN(T_BOOL_CAST);
}
<ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("unset"){TABS_AND_SPACES}")" {
- return T_UNSET_CAST;
+ RETURN_TOKEN(T_UNSET_CAST);
}
<ST_IN_SCRIPTING>"eval" {
- return T_EVAL;
+ RETURN_TOKEN(T_EVAL);
}
<ST_IN_SCRIPTING>"include" {
- return T_INCLUDE;
+ RETURN_TOKEN(T_INCLUDE);
}
<ST_IN_SCRIPTING>"include_once" {
- return T_INCLUDE_ONCE;
+ RETURN_TOKEN(T_INCLUDE_ONCE);
}
<ST_IN_SCRIPTING>"require" {
- return T_REQUIRE;
+ RETURN_TOKEN(T_REQUIRE);
}
<ST_IN_SCRIPTING>"require_once" {
- return T_REQUIRE_ONCE;
+ RETURN_TOKEN(T_REQUIRE_ONCE);
}
<ST_IN_SCRIPTING>"namespace" {
- return T_NAMESPACE;
+ RETURN_TOKEN(T_NAMESPACE);
}
<ST_IN_SCRIPTING>"use" {
- return T_USE;
+ RETURN_TOKEN(T_USE);
}
<ST_IN_SCRIPTING>"insteadof" {
- return T_INSTEADOF;
+ RETURN_TOKEN(T_INSTEADOF);
}
<ST_IN_SCRIPTING>"global" {
- return T_GLOBAL;
+ RETURN_TOKEN(T_GLOBAL);
}
<ST_IN_SCRIPTING>"isset" {
- return T_ISSET;
+ RETURN_TOKEN(T_ISSET);
}
<ST_IN_SCRIPTING>"empty" {
- return T_EMPTY;
+ RETURN_TOKEN(T_EMPTY);
}
<ST_IN_SCRIPTING>"__halt_compiler" {
- return T_HALT_COMPILER;
+ RETURN_TOKEN(T_HALT_COMPILER);
}
<ST_IN_SCRIPTING>"static" {
- return T_STATIC;
+ RETURN_TOKEN(T_STATIC);
}
<ST_IN_SCRIPTING>"abstract" {
- return T_ABSTRACT;
+ RETURN_TOKEN(T_ABSTRACT);
}
<ST_IN_SCRIPTING>"final" {
- return T_FINAL;
+ RETURN_TOKEN(T_FINAL);
}
<ST_IN_SCRIPTING>"private" {
- return T_PRIVATE;
+ RETURN_TOKEN(T_PRIVATE);
}
<ST_IN_SCRIPTING>"protected" {
- return T_PROTECTED;
+ RETURN_TOKEN(T_PROTECTED);
}
<ST_IN_SCRIPTING>"public" {
- return T_PUBLIC;
+ RETURN_TOKEN(T_PUBLIC);
}
<ST_IN_SCRIPTING>"unset" {
- return T_UNSET;
+ RETURN_TOKEN(T_UNSET);
}
<ST_IN_SCRIPTING>"=>" {
- return T_DOUBLE_ARROW;
+ RETURN_TOKEN(T_DOUBLE_ARROW);
}
<ST_IN_SCRIPTING>"list" {
- return T_LIST;
+ RETURN_TOKEN(T_LIST);
}
<ST_IN_SCRIPTING>"array" {
- return T_ARRAY;
+ RETURN_TOKEN(T_ARRAY);
}
<ST_IN_SCRIPTING>"callable" {
- return T_CALLABLE;
+ RETURN_TOKEN(T_CALLABLE);
}
<ST_IN_SCRIPTING>"++" {
- return T_INC;
+ RETURN_TOKEN(T_INC);
}
<ST_IN_SCRIPTING>"--" {
- return T_DEC;
+ RETURN_TOKEN(T_DEC);
}
<ST_IN_SCRIPTING>"===" {
- return T_IS_IDENTICAL;
+ RETURN_TOKEN(T_IS_IDENTICAL);
}
<ST_IN_SCRIPTING>"!==" {
- return T_IS_NOT_IDENTICAL;
+ RETURN_TOKEN(T_IS_NOT_IDENTICAL);
}
<ST_IN_SCRIPTING>"==" {
- return T_IS_EQUAL;
+ RETURN_TOKEN(T_IS_EQUAL);
}
<ST_IN_SCRIPTING>"!="|"<>" {
- return T_IS_NOT_EQUAL;
+ RETURN_TOKEN(T_IS_NOT_EQUAL);
}
<ST_IN_SCRIPTING>"<=>" {
- return T_SPACESHIP;
+ RETURN_TOKEN(T_SPACESHIP);
}
<ST_IN_SCRIPTING>"<=" {
- return T_IS_SMALLER_OR_EQUAL;
+ RETURN_TOKEN(T_IS_SMALLER_OR_EQUAL);
}
<ST_IN_SCRIPTING>">=" {
- return T_IS_GREATER_OR_EQUAL;
+ RETURN_TOKEN(T_IS_GREATER_OR_EQUAL);
}
<ST_IN_SCRIPTING>"+=" {
- return T_PLUS_EQUAL;
+ RETURN_TOKEN(T_PLUS_EQUAL);
}
<ST_IN_SCRIPTING>"-=" {
- return T_MINUS_EQUAL;
+ RETURN_TOKEN(T_MINUS_EQUAL);
}
<ST_IN_SCRIPTING>"*=" {
- return T_MUL_EQUAL;
+ RETURN_TOKEN(T_MUL_EQUAL);
}
<ST_IN_SCRIPTING>"*\*" {
- return T_POW;
+ RETURN_TOKEN(T_POW);
}
<ST_IN_SCRIPTING>"*\*=" {
- return T_POW_EQUAL;
+ RETURN_TOKEN(T_POW_EQUAL);
}
<ST_IN_SCRIPTING>"/=" {
- return T_DIV_EQUAL;
+ RETURN_TOKEN(T_DIV_EQUAL);
}
<ST_IN_SCRIPTING>".=" {
- return T_CONCAT_EQUAL;
+ RETURN_TOKEN(T_CONCAT_EQUAL);
}
<ST_IN_SCRIPTING>"%=" {
- return T_MOD_EQUAL;
+ RETURN_TOKEN(T_MOD_EQUAL);
}
<ST_IN_SCRIPTING>"<<=" {
- return T_SL_EQUAL;
+ RETURN_TOKEN(T_SL_EQUAL);
}
<ST_IN_SCRIPTING>">>=" {
- return T_SR_EQUAL;
+ RETURN_TOKEN(T_SR_EQUAL);
}
<ST_IN_SCRIPTING>"&=" {
- return T_AND_EQUAL;
+ RETURN_TOKEN(T_AND_EQUAL);
}
<ST_IN_SCRIPTING>"|=" {
- return T_OR_EQUAL;
+ RETURN_TOKEN(T_OR_EQUAL);
}
<ST_IN_SCRIPTING>"^=" {
- return T_XOR_EQUAL;
+ RETURN_TOKEN(T_XOR_EQUAL);
}
<ST_IN_SCRIPTING>"||" {
- return T_BOOLEAN_OR;
+ RETURN_TOKEN(T_BOOLEAN_OR);
}
<ST_IN_SCRIPTING>"&&" {
- return T_BOOLEAN_AND;
+ RETURN_TOKEN(T_BOOLEAN_AND);
}
<ST_IN_SCRIPTING>"OR" {
- return T_LOGICAL_OR;
+ RETURN_TOKEN(T_LOGICAL_OR);
}
<ST_IN_SCRIPTING>"AND" {
- return T_LOGICAL_AND;
+ RETURN_TOKEN(T_LOGICAL_AND);
}
<ST_IN_SCRIPTING>"XOR" {
- return T_LOGICAL_XOR;
+ RETURN_TOKEN(T_LOGICAL_XOR);
}
<ST_IN_SCRIPTING>"<<" {
- return T_SL;
+ RETURN_TOKEN(T_SL);
}
<ST_IN_SCRIPTING>">>" {
- return T_SR;
+ RETURN_TOKEN(T_SR);
}
<ST_IN_SCRIPTING>{TOKENS} {
- return yytext[0];
+ RETURN_TOKEN(yytext[0]);
}
<ST_IN_SCRIPTING>"{" {
yy_push_state(ST_IN_SCRIPTING);
- return '{';
+ RETURN_TOKEN('{');
}
<ST_DOUBLE_QUOTES,ST_BACKQUOTE,ST_HEREDOC>"${" {
yy_push_state(ST_LOOKING_FOR_VARNAME);
- return T_DOLLAR_OPEN_CURLY_BRACES;
+ RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES);
}
@@ -1578,7 +1601,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
if (!zend_stack_is_empty(&SCNG(state_stack))) {
yy_pop_state();
}
- return '}';
+ RETURN_TOKEN('}');
}
@@ -1587,7 +1610,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
zend_copy_value(zendlval, yytext, yyleng);
yy_pop_state();
yy_push_state(ST_IN_SCRIPTING);
- return T_STRING_VARNAME;
+ RETURN_TOKEN(T_STRING_VARNAME);
}
@@ -1617,12 +1640,12 @@ NEWLINE ("\r"|"\n"|"\r\n")
ZVAL_LONG(zendlval, ZEND_STRTOL(bin, &end, 2));
ZEND_ASSERT(!errno && end == yytext + yyleng);
}
- return T_LNUMBER;
+ RETURN_TOKEN(T_LNUMBER);
} else {
ZVAL_DOUBLE(zendlval, zend_bin_strtod(bin, (const char **)&end));
/* errno isn't checked since we allow HUGE_VAL/INF overflow */
ZEND_ASSERT(end == yytext + yyleng);
- return T_DNUMBER;
+ RETURN_TOKEN(T_DNUMBER);
}
}
@@ -1636,7 +1659,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
*/
if (end != yytext + yyleng) {
zend_throw_exception(zend_get_parse_error(), "Invalid numeric literal", E_PARSE);
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
} else {
errno = 0;
@@ -1653,19 +1676,19 @@ NEWLINE ("\r"|"\n"|"\r\n")
if (end != yytext + yyleng) {
zend_throw_exception(zend_get_parse_error(),
"Invalid numeric literal", E_PARSE);
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
ZEND_ASSERT(!errno);
- return T_DNUMBER;
+ RETURN_TOKEN(T_DNUMBER);
}
/* Also not an assert for the same reason */
if (end != yytext + yyleng) {
zend_throw_exception(zend_get_parse_error(), "Invalid numeric literal", E_PARSE);
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
}
ZEND_ASSERT(!errno);
- return T_LNUMBER;
+ RETURN_TOKEN(T_LNUMBER);
}
<ST_IN_SCRIPTING>{HNUM} {
@@ -1687,12 +1710,12 @@ NEWLINE ("\r"|"\n"|"\r\n")
ZVAL_LONG(zendlval, ZEND_STRTOL(hex, &end, 16));
ZEND_ASSERT(!errno && end == hex + len);
}
- return T_LNUMBER;
+ RETURN_TOKEN(T_LNUMBER);
} else {
ZVAL_DOUBLE(zendlval, zend_hex_strtod(hex, (const char **)&end));
/* errno isn't checked since we allow HUGE_VAL/INF overflow */
ZEND_ASSERT(end == hex + len);
- return T_DNUMBER;
+ RETURN_TOKEN(T_DNUMBER);
}
}
@@ -1709,12 +1732,12 @@ NEWLINE ("\r"|"\n"|"\r\n")
string:
ZVAL_STRINGL(zendlval, yytext, yyleng);
}
- return T_NUM_STRING;
+ RETURN_TOKEN(T_NUM_STRING);
}
<ST_VAR_OFFSET>{LNUM}|{HNUM}|{BNUM} { /* Offset must be treated as a string */
ZVAL_STRINGL(zendlval, yytext, yyleng);
- return T_NUM_STRING;
+ RETURN_TOKEN(T_NUM_STRING);
}
<ST_IN_SCRIPTING>{DNUM}|{EXPONENT_DNUM} {
@@ -1723,59 +1746,59 @@ string:
ZVAL_DOUBLE(zendlval, zend_strtod(yytext, &end));
/* errno isn't checked since we allow HUGE_VAL/INF overflow */
ZEND_ASSERT(end == yytext + yyleng);
- return T_DNUMBER;
+ RETURN_TOKEN(T_DNUMBER);
}
<ST_IN_SCRIPTING>"__CLASS__" {
- return T_CLASS_C;
+ RETURN_TOKEN(T_CLASS_C);
}
<ST_IN_SCRIPTING>"__TRAIT__" {
- return T_TRAIT_C;
+ RETURN_TOKEN(T_TRAIT_C);
}
<ST_IN_SCRIPTING>"__FUNCTION__" {
- return T_FUNC_C;
+ RETURN_TOKEN(T_FUNC_C);
}
<ST_IN_SCRIPTING>"__METHOD__" {
- return T_METHOD_C;
+ RETURN_TOKEN(T_METHOD_C);
}
<ST_IN_SCRIPTING>"__LINE__" {
- return T_LINE;
+ RETURN_TOKEN(T_LINE);
}
<ST_IN_SCRIPTING>"__FILE__" {
- return T_FILE;
+ RETURN_TOKEN(T_FILE);
}
<ST_IN_SCRIPTING>"__DIR__" {
- return T_DIR;
+ RETURN_TOKEN(T_DIR);
}
<ST_IN_SCRIPTING>"__NAMESPACE__" {
- return T_NS_C;
+ RETURN_TOKEN(T_NS_C);
}
<INITIAL>"<?=" {
BEGIN(ST_IN_SCRIPTING);
- return T_OPEN_TAG_WITH_ECHO;
+ RETURN_TOKEN(T_OPEN_TAG_WITH_ECHO);
}
<INITIAL>"<?php"([ \t]|{NEWLINE}) {
HANDLE_NEWLINE(yytext[yyleng-1]);
BEGIN(ST_IN_SCRIPTING);
- return T_OPEN_TAG;
+ RETURN_TOKEN(T_OPEN_TAG);
}
<INITIAL>"<?" {
if (CG(short_tags)) {
BEGIN(ST_IN_SCRIPTING);
- return T_OPEN_TAG;
+ RETURN_TOKEN(T_OPEN_TAG);
} else {
goto inline_char_handler;
}
@@ -1783,7 +1806,7 @@ string:
<INITIAL>{ANY_CHAR} {
if (YYCURSOR > YYLIMIT) {
- return 0;
+ RETURN_TOKEN(END);
}
inline_char_handler:
@@ -1823,7 +1846,7 @@ inline_char_handler:
ZVAL_STRINGL(zendlval, yytext, yyleng);
}
HANDLE_NEWLINES(yytext, yyleng);
- return T_INLINE_HTML;
+ RETURN_TOKEN(T_INLINE_HTML);
}
@@ -1834,7 +1857,7 @@ inline_char_handler:
yyless(yyleng - 3);
yy_push_state(ST_LOOKING_FOR_PROPERTY);
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
/* A [ always designates a variable offset, regardless of what follows
@@ -1843,22 +1866,22 @@ inline_char_handler:
yyless(yyleng - 1);
yy_push_state(ST_VAR_OFFSET);
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
<ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE,ST_VAR_OFFSET>"$"{LABEL} {
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
- return T_VARIABLE;
+ RETURN_TOKEN(T_VARIABLE);
}
<ST_VAR_OFFSET>"]" {
yy_pop_state();
- return ']';
+ RETURN_TOKEN(']');
}
<ST_VAR_OFFSET>{TOKENS}|[{}"`] {
/* Only '[' can be valid, but returning other tokens will allow a more explicit parse error */
- return yytext[0];
+ RETURN_TOKEN(yytext[0]);
}
<ST_VAR_OFFSET>[ \n\r\t\\'#] {
@@ -1866,12 +1889,12 @@ inline_char_handler:
yyless(0);
yy_pop_state();
ZVAL_NULL(zendlval);
- return T_ENCAPSED_AND_WHITESPACE;
+ RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE);
}
<ST_IN_SCRIPTING,ST_VAR_OFFSET>{LABEL} {
zend_copy_value(zendlval, yytext, yyleng);
- return T_STRING;
+ RETURN_TOKEN(T_STRING);
}
@@ -1901,7 +1924,7 @@ inline_char_handler:
yyleng = YYCURSOR - SCNG(yy_text);
- return T_COMMENT;
+ RETURN_TOKEN(T_COMMENT);
}
<ST_IN_SCRIPTING>"/*"|"/**"{WHITESPACE} {
@@ -1931,15 +1954,15 @@ inline_char_handler:
if (doc_com) {
CG(doc_comment) = zend_string_init(yytext, yyleng, 0);
- return T_DOC_COMMENT;
+ RETURN_TOKEN(T_DOC_COMMENT);
}
- return T_COMMENT;
+ RETURN_TOKEN(T_COMMENT);
}
<ST_IN_SCRIPTING>"?>"{NEWLINE}? {
BEGIN(INITIAL);
- return T_CLOSE_TAG; /* implicit ';' at php-end tag */
+ RETURN_TOKEN(T_CLOSE_TAG); /* implicit ';' at php-end tag */
}
@@ -1965,7 +1988,7 @@ inline_char_handler:
* for ' (unrecognized by parser), instead of old flex fallback to "Unexpected character..."
* rule, which continued in ST_IN_SCRIPTING state after the quote */
ZVAL_NULL(zendlval);
- return T_ENCAPSED_AND_WHITESPACE;
+ RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE);
}
}
@@ -2008,7 +2031,7 @@ inline_char_handler:
SCNG(output_filter)((unsigned char **)&str, &sz, (unsigned char *)s, (size_t)Z_STRLEN_P(zendlval));
ZVAL_STRINGL(zendlval, str, sz);
}
- return T_CONSTANT_ENCAPSED_STRING;
+ RETURN_TOKEN(T_CONSTANT_ENCAPSED_STRING);
}
@@ -2020,9 +2043,9 @@ inline_char_handler:
case '"':
yyleng = YYCURSOR - SCNG(yy_text);
if (zend_scan_escape_string(zendlval, yytext+bprefix+1, yyleng-bprefix-2, '"') == FAILURE) {
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
- return T_CONSTANT_ENCAPSED_STRING;
+ RETURN_TOKEN(T_CONSTANT_ENCAPSED_STRING);
case '$':
if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
break;
@@ -2052,7 +2075,7 @@ inline_char_handler:
YYCURSOR = SCNG(yy_text) + yyleng;
BEGIN(ST_DOUBLE_QUOTES);
- return '"';
+ RETURN_TOKEN('"');
}
@@ -2100,13 +2123,13 @@ inline_char_handler:
zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) heredoc_label);
- return T_START_HEREDOC;
+ RETURN_TOKEN(T_START_HEREDOC);
}
<ST_IN_SCRIPTING>[`] {
BEGIN(ST_BACKQUOTE);
- return '`';
+ RETURN_TOKEN('`');
}
@@ -2120,7 +2143,7 @@ inline_char_handler:
efree(heredoc_label);
BEGIN(ST_IN_SCRIPTING);
- return T_END_HEREDOC;
+ RETURN_TOKEN(T_END_HEREDOC);
}
@@ -2128,18 +2151,18 @@ inline_char_handler:
Z_LVAL_P(zendlval) = (zend_long) '{';
yy_push_state(ST_IN_SCRIPTING);
yyless(1);
- return T_CURLY_OPEN;
+ RETURN_TOKEN(T_CURLY_OPEN);
}
<ST_DOUBLE_QUOTES>["] {
BEGIN(ST_IN_SCRIPTING);
- return '"';
+ RETURN_TOKEN('"');
}
<ST_BACKQUOTE>[`] {
BEGIN(ST_IN_SCRIPTING);
- return '`';
+ RETURN_TOKEN('`');
}
@@ -2152,7 +2175,7 @@ inline_char_handler:
}
if (YYCURSOR > YYLIMIT) {
- return 0;
+ RETURN_TOKEN(END);
}
if (yytext[0] == '\\' && YYCURSOR < YYLIMIT) {
YYCURSOR++;
@@ -2189,15 +2212,15 @@ double_quotes_scan_done:
yyleng = YYCURSOR - SCNG(yy_text);
if (zend_scan_escape_string(zendlval, yytext, yyleng, '"') == FAILURE) {
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
- return T_ENCAPSED_AND_WHITESPACE;
+ RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE);
}
<ST_BACKQUOTE>{ANY_CHAR} {
if (YYCURSOR > YYLIMIT) {
- return 0;
+ RETURN_TOKEN(END);
}
if (yytext[0] == '\\' && YYCURSOR < YYLIMIT) {
YYCURSOR++;
@@ -2233,9 +2256,9 @@ double_quotes_scan_done:
yyleng = YYCURSOR - SCNG(yy_text);
if (zend_scan_escape_string(zendlval, yytext, yyleng, '`') == FAILURE) {
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
- return T_ENCAPSED_AND_WHITESPACE;
+ RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE);
}
@@ -2245,7 +2268,7 @@ double_quotes_scan_done:
zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
if (YYCURSOR > YYLIMIT) {
- return 0;
+ RETURN_TOKEN(END);
}
YYCURSOR--;
@@ -2309,9 +2332,9 @@ heredoc_scan_done:
yyleng = YYCURSOR - SCNG(yy_text);
if (zend_scan_escape_string(zendlval, yytext, yyleng - newline, 0) == FAILURE) {
- return T_ERROR;
+ RETURN_TOKEN(T_ERROR);
}
- return T_ENCAPSED_AND_WHITESPACE;
+ RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE);
}
@@ -2321,7 +2344,7 @@ heredoc_scan_done:
zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
if (YYCURSOR > YYLIMIT) {
- return 0;
+ RETURN_TOKEN(END);
}
YYCURSOR--;
@@ -2368,13 +2391,13 @@ nowdoc_scan_done:
zend_copy_value(zendlval, yytext, yyleng - newline);
HANDLE_NEWLINES(yytext, yyleng - newline);
- return T_ENCAPSED_AND_WHITESPACE;
+ RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE);
}
<ST_IN_SCRIPTING,ST_VAR_OFFSET>{ANY_CHAR} {
if (YYCURSOR > YYLIMIT) {
- return 0;
+ RETURN_TOKEN(END);
}
zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
diff --git a/Zend/zend_long.h b/Zend/zend_long.h
index 1acd2cfb08..4c81105438 100644
--- a/Zend/zend_long.h
+++ b/Zend/zend_long.h
@@ -25,7 +25,7 @@
#include "main/php_stdint.h"
/* This is the heart of the whole int64 enablement in zval. */
-#if defined(__X86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64)
+#if defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64)
# define ZEND_ENABLE_ZVAL_LONG64 1
#endif
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 363ea139d6..74ae382df4 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -265,15 +265,14 @@ static void zend_std_call_issetter(zval *object, zval *member, zval *retval) /*
static zend_always_inline int zend_verify_property_access(zend_property_info *property_info, zend_class_entry *ce) /* {{{ */
{
- switch (property_info->flags & ZEND_ACC_PPP_MASK) {
- case ZEND_ACC_PUBLIC:
- return 1;
- case ZEND_ACC_PROTECTED:
- return zend_check_protected(property_info->ce, EG(scope));
- case ZEND_ACC_PRIVATE:
- return (ce == EG(scope) || property_info->ce == EG(scope));
+ if (property_info->flags & ZEND_ACC_PUBLIC) {
+ return 1;
+ } else if (property_info->flags & ZEND_ACC_PRIVATE) {
+ return (ce == EG(scope) || property_info->ce == EG(scope));
+ } else {
+ ZEND_ASSERT(property_info->flags & ZEND_ACC_PROTECTED);
+ return zend_check_protected(property_info->ce, EG(scope));
}
- return 0;
}
/* }}} */
@@ -673,7 +672,7 @@ write_std_property:
if (Z_REFCOUNTED_P(value)) {
if (Z_ISREF_P(value)) {
/* if we assign referenced variable, we should separate it */
- ZVAL_DUP(&tmp, Z_REFVAL_P(value));
+ ZVAL_COPY(&tmp, Z_REFVAL_P(value));
value = &tmp;
} else {
Z_ADDREF_P(value);
@@ -1256,8 +1255,10 @@ ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *p
goto undeclared_property;
}
- if (UNEXPECTED(zend_update_class_constants(ce)) != SUCCESS) {
- return NULL;
+ if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) {
+ if (UNEXPECTED(zend_update_class_constants(ce)) != SUCCESS) {
+ return NULL;
+ }
}
ret = CE_STATIC_MEMBERS(ce) + property_info->offset;
diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c
index 2826c322a9..9007661f03 100644
--- a/Zend/zend_objects.c
+++ b/Zend/zend_objects.c
@@ -164,7 +164,8 @@ ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *o
dst++;
} while (src != end);
}
- if (old_object->properties) {
+ if (old_object->properties &&
+ EXPECTED(zend_hash_num_elements(old_object->properties))) {
zval *prop, new_prop;
zend_ulong num_key;
zend_string *key;
@@ -172,6 +173,9 @@ ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *o
if (!new_object->properties) {
ALLOC_HASHTABLE(new_object->properties);
zend_hash_init(new_object->properties, zend_hash_num_elements(old_object->properties), NULL, ZVAL_PTR_DTOR, 0);
+ zend_hash_real_init(new_object->properties, 0);
+ } else {
+ zend_hash_extend(new_object->properties, new_object->properties->nNumUsed + zend_hash_num_elements(old_object->properties), 0);
}
ZEND_HASH_FOREACH_KEY_VAL(old_object->properties, num_key, key, prop) {
@@ -181,8 +185,8 @@ ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *o
ZVAL_COPY_VALUE(&new_prop, prop);
zval_add_ref(&new_prop);
}
- if (key) {
- zend_hash_add_new(new_object->properties, key, &new_prop);
+ if (EXPECTED(key)) {
+ _zend_hash_append(new_object->properties, key, &new_prop);
} else {
zend_hash_index_add_new(new_object->properties, num_key, &new_prop);
}
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index f24fc9f193..abb91b1ee3 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -180,6 +180,7 @@ ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce)
#else
ce->static_members_table = NULL;
#endif
+ ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
while (p != end) {
i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
p++;
@@ -409,6 +410,10 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
}
if (arg_info[i].class_name) {
zend_string_release(arg_info[i].class_name);
+
+ if (arg_info[i].lower_class_name) {
+ zend_string_release(arg_info[i].lower_class_name);
+ }
}
}
efree(arg_info);
@@ -666,6 +671,20 @@ static void zend_resolve_finally_ret(zend_op_array *op_array, uint32_t op_num)
}
}
+static uint32_t zend_get_brk_cont_target(const zend_op_array *op_array, const zend_op *opline) {
+ int nest_levels = opline->op2.num;
+ int array_offset = opline->op1.num;
+ zend_brk_cont_element *jmp_to;
+ do {
+ jmp_to = &op_array->brk_cont_array[array_offset];
+ if (nest_levels > 1) {
+ array_offset = jmp_to->parent;
+ }
+ } while (--nest_levels > 0);
+
+ return opline->opcode == ZEND_BRK ? jmp_to->brk : jmp_to->cont;
+}
+
static void zend_resolve_finally_calls(zend_op_array *op_array)
{
uint32_t i, j;
@@ -681,22 +700,8 @@ static void zend_resolve_finally_calls(zend_op_array *op_array)
break;
case ZEND_BRK:
case ZEND_CONT:
- {
- int nest_levels, array_offset;
- zend_brk_cont_element *jmp_to;
-
- nest_levels = Z_LVAL(op_array->literals[opline->op2.constant]);
- if ((array_offset = opline->op1.opline_num) != -1) {
- do {
- jmp_to = &op_array->brk_cont_array[array_offset];
- if (nest_levels > 1) {
- array_offset = jmp_to->parent;
- }
- } while (--nest_levels > 0);
- zend_resolve_finally_call(op_array, i, opline->opcode == ZEND_BRK ? jmp_to->brk : jmp_to->cont);
- break;
- }
- }
+ zend_resolve_finally_call(op_array, i, zend_get_brk_cont_target(op_array, opline));
+ break;
case ZEND_GOTO:
if (Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) != IS_LONG) {
uint32_t num = opline->op2.constant;
@@ -774,6 +779,16 @@ ZEND_API int pass_two(zend_op_array *op_array)
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:
+ {
+ uint32_t jmp_target = zend_get_brk_cont_target(op_array, opline);
+ opline->opcode = ZEND_JMP;
+ opline->op1.opline_num = jmp_target;
+ opline->op2.num = 0;
+ ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1);
+ }
+ break;
case ZEND_GOTO:
if (Z_TYPE_P(RT_CONSTANT(op_array, opline->op2)) != IS_LONG) {
zend_resolve_goto_label(op_array, opline, 1);
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index e384031ddb..a6172179f5 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -209,7 +209,7 @@ try_again:
(op) = &(holder); \
break; \
case IS_OBJECT: \
- ZVAL_DUP(&(holder), op); \
+ ZVAL_COPY(&(holder), op); \
convert_to_long_base(&(holder), 10); \
if (Z_TYPE(holder) == IS_LONG) { \
(op) = &(holder); \
@@ -312,7 +312,7 @@ ZEND_API void ZEND_FASTCALL convert_to_long_base(zval *op, int base) /* {{{ */
break;
case IS_ARRAY:
tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
- zval_dtor(op);
+ zval_ptr_dtor(op);
ZVAL_LONG(op, tmp);
break;
case IS_OBJECT:
@@ -369,7 +369,7 @@ ZEND_API void ZEND_FASTCALL convert_to_double(zval *op) /* {{{ */
break;
case IS_ARRAY:
tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
- zval_dtor(op);
+ zval_ptr_dtor(op);
ZVAL_DOUBLE(op, tmp);
break;
case IS_OBJECT:
@@ -408,7 +408,7 @@ ZEND_API void ZEND_FASTCALL convert_to_null(zval *op) /* {{{ */
}
}
- zval_dtor(op);
+ zval_ptr_dtor(op);
ZVAL_NULL(op);
}
/* }}} */
@@ -452,7 +452,7 @@ ZEND_API void ZEND_FASTCALL convert_to_boolean(zval *op) /* {{{ */
break;
case IS_ARRAY:
tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
- zval_dtor(op);
+ zval_ptr_dtor(op);
ZVAL_BOOL(op, tmp);
break;
case IS_OBJECT:
@@ -516,7 +516,7 @@ ZEND_API void ZEND_FASTCALL _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{
}
case IS_ARRAY:
zend_error(E_NOTICE, "Array to string conversion");
- zval_dtor(op);
+ zval_ptr_dtor(op);
ZVAL_NEW_STR(op, zend_string_init("Array", sizeof("Array")-1, 0));
break;
case IS_OBJECT: {
@@ -603,14 +603,10 @@ ZEND_API void ZEND_FASTCALL convert_to_object(zval *op) /* {{{ */
switch (Z_TYPE_P(op)) {
case IS_ARRAY:
{
- HashTable *properties = emalloc(sizeof(HashTable));
- zend_array *arr = Z_ARR_P(op);
-
- memcpy(properties, Z_ARRVAL_P(op), sizeof(HashTable));
- object_and_properties_init(op, zend_standard_class_def, properties);
- if (--GC_REFCOUNT(arr) == 0) {
- efree_size(arr, sizeof(zend_array));
- }
+ zval tmp;
+ ZVAL_COPY_VALUE(&tmp, op);
+ SEPARATE_ARRAY(&tmp);
+ object_and_properties_init(op, zend_standard_class_def, Z_ARR(tmp));
break;
}
case IS_OBJECT:
@@ -1249,11 +1245,20 @@ try_again:
case IS_STRING: {
size_t i;
- ZVAL_NEW_STR(result, zend_string_alloc(Z_STRLEN_P(op1), 0));
- for (i = 0; i < Z_STRLEN_P(op1); i++) {
- Z_STRVAL_P(result)[i] = ~Z_STRVAL_P(op1)[i];
+ if (Z_STRLEN_P(op1) == 1) {
+ zend_uchar not = (zend_uchar) ~*Z_STRVAL_P(op1);
+ if (CG(one_char_string)[not]) {
+ ZVAL_INTERNED_STR(result, CG(one_char_string)[not]);
+ } else {
+ ZVAL_NEW_STR(result, zend_string_init((char *) &not, 1, 0));
+ }
+ } else {
+ ZVAL_NEW_STR(result, zend_string_alloc(Z_STRLEN_P(op1), 0));
+ for (i = 0; i < Z_STRLEN_P(op1); i++) {
+ Z_STRVAL_P(result)[i] = ~Z_STRVAL_P(op1)[i];
+ }
+ Z_STRVAL_P(result)[i] = 0;
}
- Z_STRVAL_P(result)[i] = 0;
return SUCCESS;
}
case IS_REFERENCE:
@@ -1280,12 +1285,21 @@ ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op
ZVAL_DEREF(op1);
ZVAL_DEREF(op2);
- if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
+ if (Z_TYPE_P(op1) == IS_STRING && EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
zval *longer, *shorter;
zend_string *str;
size_t i;
- if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
+ if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) {
+ if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) {
+ zend_uchar or = (zend_uchar) (*Z_STRVAL_P(op1) | *Z_STRVAL_P(op2));
+ if (CG(one_char_string)[or]) {
+ ZVAL_INTERNED_STR(result, CG(one_char_string)[or]);
+ } else {
+ ZVAL_NEW_STR(result, zend_string_init((char *) &or, 1, 0));
+ }
+ return SUCCESS;
+ }
longer = op1;
shorter = op2;
} else {
@@ -1343,7 +1357,16 @@ ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *o
zend_string *str;
size_t i;
- if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
+ if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) {
+ if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) {
+ zend_uchar and = (zend_uchar) (*Z_STRVAL_P(op1) & *Z_STRVAL_P(op2));
+ if (CG(one_char_string)[and]) {
+ ZVAL_INTERNED_STR(result, CG(one_char_string)[and]);
+ } else {
+ ZVAL_NEW_STR(result, zend_string_init((char *) &and, 1, 0));
+ }
+ return SUCCESS;
+ }
longer = op1;
shorter = op2;
} else {
@@ -1364,7 +1387,7 @@ 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_or_function);
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_AND, bitwise_and_function);
op1_lval = _zval_get_long_func(op1);
} else {
op1_lval = Z_LVAL_P(op1);
@@ -1401,7 +1424,16 @@ ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *o
zend_string *str;
size_t i;
- if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
+ if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) {
+ if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) {
+ zend_uchar xor = (zend_uchar) (*Z_STRVAL_P(op1) ^ *Z_STRVAL_P(op2));
+ if (CG(one_char_string)[xor]) {
+ ZVAL_INTERNED_STR(result, CG(one_char_string)[xor]);
+ } else {
+ ZVAL_NEW_STR(result, zend_string_init((char *) &xor, 1, 0));
+ }
+ return SUCCESS;
+ }
longer = op1;
shorter = op2;
} else {
@@ -1422,7 +1454,7 @@ 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_or_function);
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_XOR, bitwise_xor_function);
op1_lval = _zval_get_long_func(op1);
} else {
op1_lval = Z_LVAL_P(op1);
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index c026f23415..17d1bcffb4 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -364,7 +364,6 @@ ZEND_API void ZEND_FASTCALL zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_D
#define convert_to_ex_master(pzv, lower_type, upper_type) \
if (Z_TYPE_P(pzv)!=upper_type) { \
- SEPARATE_ZVAL_IF_NOT_REF(pzv); \
convert_to_##lower_type(pzv); \
}
@@ -400,7 +399,6 @@ ZEND_API void ZEND_FASTCALL zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_D
#define convert_to_explicit_type_ex(pzv, str_type) \
if (Z_TYPE_P(pzv) != str_type) { \
- SEPARATE_ZVAL_IF_NOT_REF(pzv); \
convert_to_explicit_type(pzv, str_type); \
}
@@ -414,7 +412,6 @@ ZEND_API void ZEND_FASTCALL zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_D
#define convert_scalar_to_number_ex(pzv) \
if (Z_TYPE_P(pzv)!=IS_LONG && Z_TYPE_P(pzv)!=IS_DOUBLE) { \
- SEPARATE_ZVAL_IF_NOT_REF(pzv); \
convert_scalar_to_number(pzv); \
}
diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h
index eca9c83f89..65455ee10f 100644
--- a/Zend/zend_portability.h
+++ b/Zend/zend_portability.h
@@ -240,6 +240,7 @@ char *alloca();
#if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__))
# define HAVE_NORETURN_ALIAS
+# define HAVE_ATTRIBUTE_WEAK
#endif
#if ZEND_DEBUG
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
index d66da1eade..63565182ce 100644
--- a/Zend/zend_types.h
+++ b/Zend/zend_types.h
@@ -229,13 +229,13 @@ struct _zend_array {
HT_HASH_EX((ht)->arData, idx)
#define HT_HASH_SIZE(ht) \
- ((-(int32_t)(ht)->nTableMask) * sizeof(uint32_t))
+ (((size_t)(uint32_t)-(int32_t)(ht)->nTableMask) * sizeof(uint32_t))
#define HT_DATA_SIZE(ht) \
- ((ht)->nTableSize * sizeof(Bucket))
+ ((size_t)(ht)->nTableSize * sizeof(Bucket))
#define HT_SIZE(ht) \
(HT_HASH_SIZE(ht) + HT_DATA_SIZE(ht))
#define HT_USED_SIZE(ht) \
- (HT_HASH_SIZE(ht) + ((ht)->nNumUsed * sizeof(Bucket)))
+ (HT_HASH_SIZE(ht) + ((size_t)(ht)->nNumUsed * sizeof(Bucket)))
#define HT_HASH_RESET(ht) \
memset(&HT_HASH(ht, (ht)->nTableMask), HT_INVALID_IDX, HT_HASH_SIZE(ht))
#define HT_HASH_RESET_PACKED(ht) do { \
@@ -802,7 +802,7 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) {
return --GC_REFCOUNT(Z_COUNTED_P(pz));
}
-#if SIZEOF_ZEND_LONG == 4
+#if SIZEOF_SIZE_T == 4
# define ZVAL_COPY_VALUE_EX(z, v, gc, t) \
do { \
uint32_t _w2 = v->value.ww.w2; \
@@ -810,14 +810,14 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) {
z->value.ww.w2 = _w2; \
Z_TYPE_INFO_P(z) = t; \
} while (0)
-#elif SIZEOF_ZEND_LONG == 8
+#elif SIZEOF_SIZE_T == 8
# define ZVAL_COPY_VALUE_EX(z, v, gc, t) \
do { \
Z_COUNTED_P(z) = gc; \
Z_TYPE_INFO_P(z) = t; \
} while (0)
#else
-# error "Unknbown SIZEOF_ZEND_LONG"
+# error "Unknown SIZEOF_SIZE_T"
#endif
#define ZVAL_COPY_VALUE(z, v) \
@@ -890,11 +890,12 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) {
#define SEPARATE_ARRAY(zv) do { \
zval *_zv = (zv); \
- if (Z_REFCOUNT_P(_zv) > 1) { \
+ zend_array *_arr = Z_ARR_P(_zv); \
+ if (GC_REFCOUNT(_arr) > 1) { \
if (!Z_IMMUTABLE_P(_zv)) { \
- Z_DELREF_P(_zv); \
+ GC_REFCOUNT(_arr)--; \
} \
- zval_copy_ctor_func(_zv); \
+ ZVAL_ARR(_zv, zend_array_dup(_arr)); \
} \
} while (0)
diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c
index 28cc7f6eed..cc3fff4416 100644
--- a/Zend/zend_virtual_cwd.c
+++ b/Zend/zend_virtual_cwd.c
@@ -54,10 +54,6 @@
# endif
#endif
-#ifndef S_IFLNK
-# define S_IFLNK 0120000
-#endif
-
#ifdef NETWARE
#include <fsio.h>
#endif
@@ -89,14 +85,6 @@ cwd_state main_cwd_state; /* True global */
#include <direct.h>
#endif
-#ifndef S_ISDIR
-#define S_ISDIR(mode) ((mode) & _S_IFDIR)
-#endif
-
-#ifndef S_ISREG
-#define S_ISREG(mode) ((mode) & _S_IFREG)
-#endif
-
#ifdef TSRM_WIN32
#include <tchar.h>
#define tsrm_strtok_r(a,b,c) _tcstok((a),(b))
@@ -237,6 +225,10 @@ CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len){
typedef BOOL (WINAPI *gfpnh_func)(HANDLE, LPTSTR, DWORD, DWORD);
gfpnh_func pGetFinalPathNameByHandle;
+ if (!target_len) {
+ return -1;
+ }
+
kernel32 = LoadLibrary("kernel32.dll");
if (kernel32) {
@@ -260,8 +252,14 @@ CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len){
return -1;
}
- dwRet = pGetFinalPathNameByHandle(hFile, target, MAXPATHLEN, VOLUME_NAME_DOS);
- if(dwRet >= MAXPATHLEN || dwRet == 0) {
+ /* Despite MSDN has documented it won't to, the length returned by
+ GetFinalPathNameByHandleA includes the length of the
+ null terminator. This behavior is at least reproducible
+ with VS2012 and earlier, and seems not to be fixed till
+ now. Thus, correcting target_len so it's suddenly don't
+ overflown. */
+ dwRet = pGetFinalPathNameByHandle(hFile, target, target_len - 1, VOLUME_NAME_DOS);
+ if(dwRet >= target_len || dwRet >= MAXPATHLEN || dwRet == 0) {
return -1;
}
@@ -555,6 +553,11 @@ CWD_API char *virtual_getcwd_ex(size_t *length) /* {{{ */
return retval;
}
#endif
+ if (!state->cwd) {
+ *length = 0;
+ return NULL;
+ }
+
*length = state->cwd_length;
return estrdup(state->cwd);
}
@@ -576,6 +579,9 @@ CWD_API char *virtual_getcwd(char *buf, size_t size) /* {{{ */
errno = ERANGE; /* Is this OK? */
return NULL;
}
+ if (!cwd) {
+ return NULL;
+ }
memcpy(buf, cwd, length+1);
efree(cwd);
return buf;
diff --git a/Zend/zend_virtual_cwd.h b/Zend/zend_virtual_cwd.h
index d7d1067828..019888757f 100644
--- a/Zend/zend_virtual_cwd.h
+++ b/Zend/zend_virtual_cwd.h
@@ -337,4 +337,33 @@ CWD_API realpath_cache_bucket** realpath_cache_get_buckets(void);
#endif
+/* Global stat declarations */
+#ifndef _S_IFDIR
+#define _S_IFDIR S_IFDIR
+#endif
+
+#ifndef _S_IFREG
+#define _S_IFREG S_IFREG
+#endif
+
+#ifndef S_IFLNK
+# define S_IFLNK 0120000
+#endif
+
+#ifndef S_ISDIR
+#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
+#endif
+
+#ifndef S_ISREG
+#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
+#endif
+
+#ifndef S_ISLNK
+#define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK)
+#endif
+
+#ifndef S_IXROOT
+#define S_IXROOT ( S_IXUSR | S_IXGRP | S_IXOTH )
+#endif
+
#endif /* VIRTUAL_CWD_H */
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 5d6b128cb3..0fe820a20f 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -164,11 +164,12 @@ ZEND_VM_HANDLER(4, ZEND_DIV, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- fast_div_function(EX_VAR(opline->result.var),
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ fast_div_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -218,11 +219,12 @@ ZEND_VM_HANDLER(6, ZEND_SL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_left_function(EX_VAR(opline->result.var),
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ shift_left_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -233,11 +235,12 @@ ZEND_VM_HANDLER(7, ZEND_SR, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_right_function(EX_VAR(opline->result.var),
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ shift_right_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -248,12 +251,58 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- concat_function(EX_VAR(opline->result.var),
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
- FREE_OP1();
+ op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+
+ do {
+ if ((OP1_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+ (OP2_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+ zend_string *op1_str = Z_STR_P(op1);
+ zend_string *op2_str = Z_STR_P(op2);
+ zend_string *str;
+
+ if (OP1_TYPE != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+ FREE_OP1();
+ break;
+ }
+ }
+ if (OP2_TYPE != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+ FREE_OP1();
+ break;
+ }
+ }
+ if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_CV &&
+ !IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+ size_t len = op1_str->len;
+
+ str = zend_string_realloc(op1_str, len + op2_str->len, 0);
+ memcpy(str->val + len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ break;
+ } else {
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ }
+ } else {
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ concat_function(EX_VAR(opline->result.var), op1, op2);
+ }
+ FREE_OP1();
+ } while (0);
FREE_OP2();
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -263,12 +312,13 @@ ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R),
- GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R));
+ op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
+ result = fast_is_identical_function(op1, op2);
FREE_OP1();
FREE_OP2();
ZEND_VM_SMART_BRANCH(result, (OP1_TYPE|OP2_TYPE) & (IS_VAR|IS_TMP_VAR));
@@ -283,12 +333,13 @@ ZEND_VM_HANDLER(16, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R),
- GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R));
+ op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
+ result = fast_is_not_identical_function(op1, op2);
FREE_OP1();
FREE_OP2();
ZEND_VM_SMART_BRANCH(result, (OP1_TYPE|OP2_TYPE) & (IS_VAR|IS_TMP_VAR));
@@ -310,18 +361,18 @@ ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -353,10 +404,10 @@ ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
} while (0);
SAVE_OPLINE();
- if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -379,18 +430,18 @@ ZEND_VM_HANDLER(18, ZEND_IS_NOT_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -422,10 +473,10 @@ ZEND_VM_HANDLER(18, ZEND_IS_NOT_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
} while (0);
SAVE_OPLINE();
- if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -543,12 +594,12 @@ ZEND_VM_HANDLER(170, ZEND_SPACESHIP, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2;
SAVE_OPLINE();
- compare_function(result,
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ compare_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -559,11 +610,12 @@ ZEND_VM_HANDLER(9, ZEND_BW_OR, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_or_function(EX_VAR(opline->result.var),
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ bitwise_or_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -574,11 +626,12 @@ ZEND_VM_HANDLER(10, ZEND_BW_AND, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_and_function(EX_VAR(opline->result.var),
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ bitwise_and_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -589,11 +642,12 @@ ZEND_VM_HANDLER(11, ZEND_BW_XOR, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_xor_function(EX_VAR(opline->result.var),
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ bitwise_xor_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -604,11 +658,12 @@ ZEND_VM_HANDLER(14, ZEND_BOOL_XOR, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- boolean_xor_function(EX_VAR(opline->result.var),
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -678,7 +733,6 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
FREE_OP2();
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
@@ -708,42 +762,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval *z;
- zval rv, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- if (Z_OBJ_HT(obj)->read_property &&
- (z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
- if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- zptr = z;
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- binary_op(z, z, value);
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- zval_ptr_dtor(zptr);
- } 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));
- }
- }
- OBJ_RELEASE(Z_OBJ(obj));
+ zend_assign_op_overloaded_property(object, property, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -775,7 +794,6 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMPVAR|
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
FREE_UNFETCHED_OP2();
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
@@ -846,7 +864,6 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|CV, CONST|TMPVAR|CV, binary_
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
FREE_OP2();
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
@@ -1091,7 +1108,7 @@ ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV)
#endif
}
-ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, incdec_t incdec_op)
+ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, int inc)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -1113,7 +1130,6 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
FREE_OP2();
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
@@ -1134,51 +1150,27 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
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)) {
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
+ }
+ } else {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
+ }
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval rv;
-
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval *z, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- incdec_op(z);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(z);
- } else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- }
+ zend_pre_incdec_overloaded_property(object, property, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -1190,15 +1182,15 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
{
- ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, incdec_op, increment_function);
+ ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, inc, 1);
}
ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
{
- ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, incdec_op, decrement_function);
+ ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, inc, 0);
}
-ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, incdec_t incdec_op)
+ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, int inc)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -1220,7 +1212,6 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|
if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
FREE_OP2();
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
@@ -1239,44 +1230,25 @@ 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)) {
- ZVAL_DEREF(zptr);
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
- zval_opt_copy_ctor(zptr);
- incdec_op(zptr);
- } else {
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval rv, obj;
- zval *z;
- zval z_copy;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
}
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- ZVAL_DUP(EX_VAR(opline->result.var), z);
- ZVAL_DUP(&z_copy, z);
- incdec_op(&z_copy);
- if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
- Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(&z_copy);
- zval_ptr_dtor(z);
} else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- ZVAL_NULL(EX_VAR(opline->result.var));
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ zval_opt_copy_ctor(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
}
+ } else {
+ zend_post_incdec_overloaded_property(object, property, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var));
}
} while (0);
@@ -1288,12 +1260,12 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|
ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
{
- ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, incdec_op, increment_function);
+ ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, inc, 1);
}
ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
{
- ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, incdec_op, decrement_function);
+ ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, inc, 0);
}
ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
@@ -1307,7 +1279,6 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
@@ -1355,7 +1326,6 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY)
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
@@ -1403,7 +1373,6 @@ ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY)
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
@@ -1444,7 +1413,6 @@ ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
@@ -1481,7 +1449,7 @@ ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMPVAR|CV, ANY)
zval *z;
SAVE_OPLINE();
- z = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ z = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
if (Z_TYPE_P(z) == IS_STRING) {
zend_string *str = Z_STR_P(z);
@@ -1494,6 +1462,8 @@ ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMPVAR|CV, ANY)
if (str->len != 0) {
zend_write(str->val, str->len);
+ } else if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(z, BP_VAR_R);
}
zend_string_release(str);
}
@@ -1513,7 +1483,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V
HashTable *target_symbol_table;
SAVE_OPLINE();
- varname = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
if (OP1_TYPE == IS_CONST) {
name = Z_STR_P(varname);
@@ -1521,6 +1491,9 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V
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);
}
@@ -1714,7 +1687,6 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE);
@@ -1738,7 +1710,6 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE);
@@ -1785,7 +1756,6 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUS
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP2();
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE);
@@ -1822,7 +1792,6 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP2();
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE);
@@ -1854,7 +1823,8 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|CV)
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
- if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (OP1_TYPE == IS_CONST ||
+ (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -1927,7 +1897,6 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMPVAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
FREE_OP2();
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
@@ -1960,7 +1929,6 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMPVAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
FREE_OP2();
- FREE_OP1_VAR_PTR();
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);
@@ -1992,7 +1960,8 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV)
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
- if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (OP1_TYPE == IS_CONST ||
+ (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -2074,7 +2043,6 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMPV
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
FREE_OP2();
- FREE_OP1_VAR_PTR();
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);
@@ -2110,7 +2078,6 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMPVAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
FREE_OP2();
- FREE_OP1_VAR_PTR();
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);
@@ -2130,7 +2097,7 @@ ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST)
zval *container;
SAVE_OPLINE();
- container = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
ZEND_VM_C_LABEL(try_fetch_list):
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
@@ -2142,7 +2109,8 @@ ZEND_VM_C_LABEL(try_fetch_list):
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
+ } 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);
@@ -2154,10 +2122,13 @@ ZEND_VM_C_LABEL(try_fetch_list):
} else {
ZVAL_NULL(result);
}
- } else if (Z_TYPE_P(container) == IS_REFERENCE) {
+ } else if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(container) == IS_REFERENCE) {
container = Z_REFVAL_P(container);
ZEND_VM_C_GOTO(try_fetch_list);
} else {
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(container, BP_VAR_R);
+ }
ZVAL_NULL(EX_VAR(opline->result.var));
}
CHECK_EXCEPTION();
@@ -2185,7 +2156,6 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_OP2();
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
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));
@@ -2214,11 +2184,9 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|CV)
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
FREE_UNFETCHED_OP2();
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
-ZEND_VM_C_LABEL(try_assign_dim):
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
ZEND_VM_C_LABEL(try_assign_dim_array):
if (OP2_TYPE == IS_UNUSED) {
@@ -2246,53 +2214,58 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
}
- } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
- zend_free_op free_op2;
- zval *property_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ } else {
+ if (EXPECTED(Z_ISREF_P(object_ptr))) {
+ object_ptr = Z_REFVAL_P(object_ptr);
+ if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+ ZEND_VM_C_GOTO(try_assign_dim_array);
+ }
+ }
+ if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+ 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);
- 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_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
- FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- FREE_OP1_VAR_PTR();
- HANDLE_EXCEPTION();
- } else {
- zend_long offset;
+ 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);
+ 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_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
+ FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
+ FREE_OP1_VAR_PTR();
+ HANDLE_EXCEPTION();
+ } else {
+ zend_long offset;
- 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_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ 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_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ }
+ } else {
+ zval_ptr_dtor_nogc(object_ptr);
+ZEND_VM_C_LABEL(assign_dim_convert_to_array):
+ ZVAL_NEW_ARR(object_ptr);
+ zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0);
+ 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 {
- zval_ptr_dtor_nogc(object_ptr);
-ZEND_VM_C_LABEL(assign_dim_convert_to_array):
- ZVAL_NEW_ARR(object_ptr);
- zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0);
- ZEND_VM_C_GOTO(try_assign_dim_array);
- }
- } else if (EXPECTED(Z_ISREF_P(object_ptr))) {
- object_ptr = Z_REFVAL_P(object_ptr);
- ZEND_VM_C_GOTO(try_assign_dim);
- } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
- if (UNEXPECTED(object_ptr == &EG(error_zval))) {
- ZEND_VM_C_GOTO(assign_dim_clean);
- }
- ZEND_VM_C_GOTO(assign_dim_convert_to_array);
- } else {
- zend_error(E_WARNING, "Cannot use a scalar value as an array");
+ 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((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- FREE_OP(free_op_data1);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ FREE_OP2();
+ value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ FREE_OP(free_op_data1);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
}
}
FREE_OP1_VAR_PTR();
@@ -2343,7 +2316,6 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
if (OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- FREE_OP2_VAR_PTR();
FREE_UNFETCHED_OP1();
HANDLE_EXCEPTION();
}
@@ -2366,7 +2338,6 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
FREE_OP2_VAR_PTR();
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
if (OP1_TYPE == IS_VAR &&
@@ -2735,28 +2706,60 @@ ZEND_VM_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
zend_string *op1_str, *op2_str, *str;
SAVE_OPLINE();
- op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
- op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
if (OP1_TYPE == IS_CONST) {
op1_str = Z_STR_P(op1);
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ op1_str = zend_string_copy(Z_STR_P(op1));
} else {
- op1_str = zval_get_string(op1);
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ op1_str = _zval_get_string_func(op1);
}
+ op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
if (OP2_TYPE == IS_CONST) {
op2_str = Z_STR_P(op2);
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ op2_str = zend_string_copy(Z_STR_P(op2));
} else {
- op2_str = zval_get_string(op2);
- }
- str = zend_string_alloc(op1_str->len + op2_str->len, 0);
- memcpy(str->val, op1_str->val, op1_str->len);
- memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
- ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
- if (OP1_TYPE != IS_CONST) {
- zend_string_release(op1_str);
- }
- if (OP2_TYPE != IS_CONST) {
- zend_string_release(op2_str);
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ op2_str = _zval_get_string_func(op2);
}
+ do {
+ if (OP1_TYPE != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ if (OP2_TYPE == IS_CONST) {
+ zend_string_addref(op2_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+ zend_string_release(op1_str);
+ break;
+ }
+ }
+ if (OP2_TYPE != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ if (OP1_TYPE == IS_CONST) {
+ zend_string_addref(op1_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+ zend_string_release(op2_str);
+ break;
+ }
+ }
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ if (OP1_TYPE != IS_CONST) {
+ zend_string_release(op1_str);
+ }
+ if (OP2_TYPE != IS_CONST) {
+ zend_string_release(op2_str);
+ }
+ } while (0);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -2776,11 +2779,22 @@ ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV)
var = GET_OP2_ZVAL_PTR(BP_VAR_R);
rope[0] = zend_string_copy(Z_STR_P(var));
} else {
- SAVE_OPLINE();
- var = GET_OP2_ZVAL_PTR(BP_VAR_R);
- rope[0] = zval_get_string(var);
- FREE_OP2();
- CHECK_EXCEPTION();
+ var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+ if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+ if (OP2_TYPE == IS_CV) {
+ rope[0] = zend_string_copy(Z_STR_P(var));
+ } else {
+ rope[0] = Z_STR_P(var);
+ }
+ } else {
+ SAVE_OPLINE();
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(var, BP_VAR_R);
+ }
+ rope[0] = _zval_get_string_func(var);
+ FREE_OP2();
+ CHECK_EXCEPTION();
+ }
}
ZEND_VM_NEXT_OPCODE();
}
@@ -2798,11 +2812,22 @@ ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV)
var = GET_OP2_ZVAL_PTR(BP_VAR_R);
rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
} else {
- SAVE_OPLINE();
- var = GET_OP2_ZVAL_PTR(BP_VAR_R);
- rope[opline->extended_value] = zval_get_string(var);
- FREE_OP2();
- CHECK_EXCEPTION();
+ var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+ if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+ if (OP2_TYPE == IS_CV) {
+ rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+ } else {
+ rope[opline->extended_value] = Z_STR_P(var);
+ }
+ } else {
+ SAVE_OPLINE();
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(var, BP_VAR_R);
+ }
+ rope[opline->extended_value] = _zval_get_string_func(var);
+ FREE_OP2();
+ CHECK_EXCEPTION();
+ }
}
ZEND_VM_NEXT_OPCODE();
}
@@ -2822,11 +2847,22 @@ ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV)
var = GET_OP2_ZVAL_PTR(BP_VAR_R);
rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
} else {
- SAVE_OPLINE();
- var = GET_OP2_ZVAL_PTR(BP_VAR_R);
- rope[opline->extended_value] = zval_get_string(var);
- FREE_OP2();
- CHECK_EXCEPTION();
+ var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+ if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+ if (OP2_TYPE == IS_CV) {
+ rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+ } else {
+ rope[opline->extended_value] = Z_STR_P(var);
+ }
+ } else {
+ SAVE_OPLINE();
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(var, BP_VAR_R);
+ }
+ rope[opline->extended_value] = _zval_get_string_func(var);
+ FREE_OP2();
+ CHECK_EXCEPTION();
+ }
}
for (i = 0; i <= opline->extended_value; i++) {
len += rope[i]->len;
@@ -2858,7 +2894,7 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMPVAR|UNUSED|CV)
ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_op2;
- zval *class_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ zval *class_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
ZEND_VM_C_LABEL(try_class_name):
if (OP2_TYPE == IS_CONST) {
@@ -2876,6 +2912,9 @@ ZEND_VM_C_LABEL(try_class_name):
class_name = Z_REFVAL_P(class_name);
ZEND_VM_C_GOTO(try_class_name);
} else {
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(class_name, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -2902,7 +2941,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR
SAVE_OPLINE();
- function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
if (OP2_TYPE != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
@@ -2913,6 +2952,9 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR
break;
}
}
+ if (OP2_TYPE == 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();
}
@@ -2923,7 +2965,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR
} while (0);
}
- object = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R);
+ object = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_R);
if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context");
@@ -2933,13 +2975,16 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR
if (OP1_TYPE != IS_UNUSED) {
do {
- if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (OP1_TYPE == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if ((OP1_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
break;
}
}
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(object, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -2986,7 +3031,8 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
- } else if (OP1_TYPE & (IS_VAR|IS_TMP_VAR)) {
+ } else if (OP1_TYPE & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+ /* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@@ -3044,9 +3090,12 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE
} else if (OP2_TYPE != IS_UNUSED) {
zend_free_op free_op2;
- function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
if (OP2_TYPE != IS_CONST) {
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (OP2_TYPE == 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();
}
@@ -3174,7 +3223,7 @@ ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMPVAR|CV)
uint32_t call_info = ZEND_CALL_NESTED_FUNCTION;
SAVE_OPLINE();
- function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
ZEND_VM_C_LABEL(try_function_name):
if (OP2_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
@@ -3354,6 +3403,9 @@ ZEND_VM_C_LABEL(try_function_name):
function_name = Z_REFVAL_P(function_name);
ZEND_VM_C_GOTO(try_function_name);
} else {
+ if (OP2_TYPE == 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();
}
@@ -3908,6 +3960,10 @@ ZEND_VM_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED)
}
}
zend_verify_return_type(EX(func), retval_ptr);
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ FREE_OP1();
+ }
#endif
}
CHECK_EXCEPTION();
@@ -3924,15 +3980,14 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
SAVE_OPLINE();
retval_ptr = GET_OP1_UNDEF_CV(retval_ptr, BP_VAR_R);
- CHECK_EXCEPTION();
- }
-
- if (!EX(return_value)) {
+ if (EX(return_value)) {
+ ZVAL_NULL(EX(return_value));
+ }
+ } else if (!EX(return_value)) {
if (OP1_TYPE == IS_VAR || OP1_TYPE == 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));
- CHECK_EXCEPTION();
}
}
} else {
@@ -3998,7 +4053,6 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
if (OP1_TYPE == IS_VAR && UNEXPECTED(retval_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot return string offsets by reference");
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
@@ -4080,7 +4134,7 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
zend_free_op free_op1;
SAVE_OPLINE();
- value = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
do {
if (OP1_TYPE == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
@@ -4090,6 +4144,9 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
break;
}
}
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(value, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -4297,7 +4354,6 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)
if (OP1_TYPE == IS_VAR && UNEXPECTED(varptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Only variables can be passed by reference");
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
@@ -4376,71 +4432,67 @@ ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY)
int arg_num;
SAVE_OPLINE();
- args = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ args = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
arg_num = ZEND_CALL_NUM_ARGS(EX(call)) + 1;
ZEND_VM_C_LABEL(send_again):
- switch (Z_TYPE_P(args)) {
- case IS_ARRAY: {
- HashTable *ht = Z_ARRVAL_P(args);
- zval *arg, *top;
- zend_string *name;
-
- zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht));
-
- if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
- uint32_t i;
- int separate = 0;
-
- /* check if any of arguments are going to be passed by reference */
- for (i = 0; i < zend_hash_num_elements(ht); i++) {
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + i)) {
- separate = 1;
- break;
- }
- }
- if (separate) {
- zval_copy_ctor(args);
- ht = Z_ARRVAL_P(args);
+ if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) {
+ HashTable *ht = Z_ARRVAL_P(args);
+ zval *arg, *top;
+ zend_string *name;
+
+ zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht));
+
+ if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
+ uint32_t i;
+ int separate = 0;
+
+ /* check if any of arguments are going to be passed by reference */
+ for (i = 0; i < zend_hash_num_elements(ht); i++) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + i)) {
+ separate = 1;
+ break;
}
}
+ if (separate) {
+ zval_copy_ctor(args);
+ ht = Z_ARRVAL_P(args);
+ }
+ }
- ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) {
- if (name) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot unpack array with string keys");
- FREE_OP1();
- HANDLE_EXCEPTION();
- }
+ ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) {
+ if (name) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot unpack array with string keys");
+ FREE_OP1();
+ HANDLE_EXCEPTION();
+ }
- top = ZEND_CALL_ARG(EX(call), arg_num);
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
- if (!Z_IMMUTABLE_P(args)) {
- ZVAL_MAKE_REF(arg);
- Z_ADDREF_P(arg);
- ZVAL_REF(top, Z_REF_P(arg));
- } else {
- ZVAL_DUP(top, arg);
- }
- } else if (Z_ISREF_P(arg)) {
- ZVAL_COPY(top, Z_REFVAL_P(arg));
+ top = ZEND_CALL_ARG(EX(call), arg_num);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+ if (!Z_IMMUTABLE_P(args)) {
+ ZVAL_MAKE_REF(arg);
+ Z_ADDREF_P(arg);
+ ZVAL_REF(top, Z_REF_P(arg));
} else {
- ZVAL_COPY(top, arg);
+ ZVAL_DUP(top, arg);
}
+ } else if (Z_ISREF_P(arg)) {
+ ZVAL_COPY(top, Z_REFVAL_P(arg));
+ } else {
+ ZVAL_COPY(top, arg);
+ }
- ZEND_CALL_NUM_ARGS(EX(call))++;
- arg_num++;
- } ZEND_HASH_FOREACH_END();
+ ZEND_CALL_NUM_ARGS(EX(call))++;
+ arg_num++;
+ } ZEND_HASH_FOREACH_END();
- break;
- }
- case IS_OBJECT: {
- zend_class_entry *ce = Z_OBJCE_P(args);
- zend_object_iterator *iter;
+ } else if (EXPECTED(Z_TYPE_P(args) == IS_OBJECT)) {
+ zend_class_entry *ce = Z_OBJCE_P(args);
+ zend_object_iterator *iter;
- if (!ce || !ce->get_iterator) {
- zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
- break;
- }
+ if (!ce || !ce->get_iterator) {
+ zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
+ } else {
iter = ce->get_iterator(ce, args, 0);
if (UNEXPECTED(!iter)) {
@@ -4518,14 +4570,15 @@ ZEND_VM_C_LABEL(send_again):
ZEND_VM_C_LABEL(unpack_iter_dtor):
zend_iterator_dtor(iter);
- break;
}
- case IS_REFERENCE:
- args = Z_REFVAL_P(args);
- ZEND_VM_C_GOTO(send_again);
- break;
- default:
- zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
+ } else if (EXPECTED(Z_ISREF_P(args))) {
+ args = Z_REFVAL_P(args);
+ ZEND_VM_C_GOTO(send_again);
+ } else {
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(args) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(args, BP_VAR_R);
+ }
+ zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
}
FREE_OP1();
@@ -4817,31 +4870,8 @@ ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY)
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(50, ZEND_BRK, ANY, CONST)
-{
- USE_OPLINE
- zend_brk_cont_element *el;
-
- SAVE_OPLINE();
- el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num,
- &EX(func)->op_array, execute_data);
- ZEND_VM_JMP(EX(func)->op_array.opcodes + el->brk);
-}
-
-ZEND_VM_HANDLER(51, ZEND_CONT, ANY, CONST)
-{
- USE_OPLINE
- zend_brk_cont_element *el;
-
- SAVE_OPLINE();
- el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num,
- &EX(func)->op_array, execute_data);
- ZEND_VM_JMP(EX(func)->op_array.opcodes + el->cont);
-}
-
ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
{
- zend_op *brk_opline;
USE_OPLINE
zend_brk_cont_element *el;
@@ -4849,14 +4879,12 @@ ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->extended_value,
&EX(func)->op_array, execute_data);
- brk_opline = EX(func)->op_array.opcodes + el->brk;
+ if (el->start >= 0) {
+ zend_op *brk_opline = EX(func)->op_array.opcodes + el->brk;
- if (brk_opline->opcode == ZEND_FREE) {
- if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
+ if (brk_opline->opcode == ZEND_FREE) {
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
- }
- } else if (brk_opline->opcode == ZEND_FE_FREE) {
- if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
+ } else if (brk_opline->opcode == ZEND_FE_FREE) {
zval *var = EX_VAR(brk_opline->op1.var);
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
@@ -4878,18 +4906,18 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -4920,10 +4948,10 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
} while (0);
SAVE_OPLINE();
- if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -4999,7 +5027,7 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|CV, ANY)
zend_object_clone_obj_t clone_call;
SAVE_OPLINE();
- obj = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R);
+ obj = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_R);
if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_OBJ_P(obj) == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context");
@@ -5014,7 +5042,10 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|CV, ANY)
if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) {
break;
}
- }
+ }
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(obj, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -5075,7 +5106,6 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
SAVE_OPLINE();
if (OP1_TYPE == IS_UNUSED) {
zend_constant *c;
- zval *retval;
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
@@ -5101,67 +5131,80 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
} else {
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c);
}
- retval = EX_VAR(opline->result.var);
- ZVAL_COPY_VALUE(retval, &c->value);
- if (Z_OPT_COPYABLE_P(retval) || Z_OPT_REFCOUNTED_P(retval)) {
- if (Z_OPT_COPYABLE_P(retval)) {
- zval_copy_ctor_func(retval);
- } else {
- Z_ADDREF_P(retval);
- }
+#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;
- if (OP1_TYPE == IS_CONST) {
- if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
- value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
- ZVAL_DEREF(value);
- ZVAL_DUP(EX_VAR(opline->result.var), value);
- ZEND_VM_C_GOTO(constant_fetch_end);
- } else if (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(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ do {
+ if (OP1_TYPE == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
+ value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
+ ZVAL_DEREF(value);
+#ifdef ZTS
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
+#endif
+ break;
+ } else if (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(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
+ if (UNEXPECTED(ce == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1)));
+ HANDLE_EXCEPTION();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
}
- if (UNEXPECTED(ce == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1)));
- 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;
}
- CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
- }
- } 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);
- ZVAL_DUP(EX_VAR(opline->result.var), value);
- ZEND_VM_C_GOTO(constant_fetch_end);
}
- }
- 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 (OP1_TYPE == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value);
+ 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);
+ }
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value);
+ zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
+ HANDLE_EXCEPTION();
}
+ } while (0);
+#ifdef ZTS
+ if (ce->type == ZEND_INTERNAL_CLASS) {
ZVAL_DUP(EX_VAR(opline->result.var), value);
} else {
- zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
+ ZVAL_COPY(EX_VAR(opline->result.var), value);
}
+#else
+ ZVAL_COPY(EX_VAR(opline->result.var), value);
+#endif
}
-ZEND_VM_C_LABEL(constant_fetch_end):
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -5173,11 +5216,10 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSE
SAVE_OPLINE();
if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ 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_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
- FREE_OP1_VAR_PTR();
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -5187,11 +5229,11 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSE
} else {
expr_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
if (OP1_TYPE == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (OP1_TYPE == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (OP1_TYPE == IS_CV) {
@@ -5217,48 +5259,46 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSE
if (OP2_TYPE != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ zval *offset = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
zend_string *str;
zend_ulong hval;
ZEND_VM_C_LABEL(add_again):
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- ZEND_VM_C_GOTO(num_index);
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-ZEND_VM_C_LABEL(num_index):
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if (OP2_TYPE != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- ZEND_VM_C_GOTO(num_index);
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if (OP2_TYPE != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ ZEND_VM_C_GOTO(num_index);
}
+ }
ZEND_VM_C_LABEL(str_index):
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- ZEND_VM_C_GOTO(str_index);
- case IS_FALSE:
- hval = 0;
- ZEND_VM_C_GOTO(num_index);
- case IS_TRUE:
- hval = 1;
- ZEND_VM_C_GOTO(num_index);
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- ZEND_VM_C_GOTO(add_again);
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+ZEND_VM_C_LABEL(num_index):
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ ZEND_VM_C_GOTO(add_again);
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ ZEND_VM_C_GOTO(str_index);
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ ZEND_VM_C_GOTO(num_index);
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ ZEND_VM_C_GOTO(num_index);
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ ZEND_VM_C_GOTO(num_index);
+ } else if (OP2_TYPE == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ ZEND_VM_C_GOTO(str_index);
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
FREE_OP2();
} else {
@@ -5392,8 +5432,7 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY)
}
}
} else {
- ZVAL_COPY_VALUE(result, expr);
- zval_opt_copy_ctor(result);
+ ZVAL_COPY(result, expr);
convert_to_object(result);
}
}
@@ -5414,10 +5453,13 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY)
zend_bool failure_retval=0;
SAVE_OPLINE();
- inc_filename = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ inc_filename = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
ZVAL_UNDEF(&tmp_inc_filename);
if (Z_TYPE_P(inc_filename) != IS_STRING) {
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(inc_filename) == IS_UNDEF)) {
+ inc_filename = GET_OP1_UNDEF_CV(inc_filename, BP_VAR_R);
+ }
ZVAL_STR(&tmp_inc_filename, zval_get_string(inc_filename));
inc_filename = &tmp_inc_filename;
}
@@ -5560,10 +5602,13 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
ZEND_VM_NEXT_OPCODE();
}
- varname = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ 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;
}
@@ -5616,6 +5661,7 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMPVAR|CV)
zval *container;
zval *offset;
zend_ulong hval;
+ zend_string *key;
SAVE_OPLINE();
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
@@ -5627,72 +5673,81 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMPVAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
FREE_UNFETCHED_OP2();
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
- offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ offset = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
-ZEND_VM_C_LABEL(unset_dim_again):
- if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht;
+ do {
+ if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ HashTable *ht;
+ZEND_VM_C_LABEL(unset_dim_array):
+ SEPARATE_ARRAY(container);
+ ht = Z_ARRVAL_P(container);
ZEND_VM_C_LABEL(offset_again):
- SEPARATE_ARRAY(container);
- ht = Z_ARRVAL_P(container);
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- zend_hash_index_del(ht, hval);
- break;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-ZEND_VM_C_LABEL(num_index_dim):
- zend_hash_index_del(ht, hval);
- break;
- case IS_STRING:
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ key = Z_STR_P(offset);
if (OP2_TYPE != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
ZEND_VM_C_GOTO(num_index_dim);
}
}
+ZEND_VM_C_LABEL(str_index_dim):
if (ht == &EG(symbol_table)) {
- zend_delete_global_variable(Z_STR_P(offset));
+ zend_delete_global_variable(key);
} else {
- zend_hash_del(ht, Z_STR_P(offset));
+ zend_hash_del(ht, key);
}
- break;
- case IS_NULL:
- zend_hash_del(ht, STR_EMPTY_ALLOC());
- break;
- case IS_FALSE:
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+ZEND_VM_C_LABEL(num_index_dim):
+ zend_hash_index_del(ht, hval);
+ } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ ZEND_VM_C_GOTO(offset_again);
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ ZEND_VM_C_GOTO(num_index_dim);
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ key = STR_EMPTY_ALLOC();
+ ZEND_VM_C_GOTO(str_index_dim);
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
ZEND_VM_C_GOTO(num_index_dim);
- case IS_TRUE:
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
ZEND_VM_C_GOTO(num_index_dim);
- case IS_RESOURCE:
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
hval = Z_RES_HANDLE_P(offset);
ZEND_VM_C_GOTO(num_index_dim);
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- ZEND_VM_C_GOTO(offset_again);
- break;
- default:
+ } else if (OP2_TYPE == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ key = STR_EMPTY_ALLOC();
+ ZEND_VM_C_GOTO(str_index_dim);
+ } else {
zend_error(E_WARNING, "Illegal offset type in unset");
- break;
+ }
+ break;
+ } else if (OP1_TYPE != IS_UNUSED && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ ZEND_VM_C_GOTO(unset_dim_array);
+ }
}
- } else if (OP1_TYPE == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
- if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
- } else {
- Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
}
- } else if (OP1_TYPE != IS_UNUSED && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- ZEND_VM_C_GOTO(unset_dim_again);
- } else if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- }
+ if (OP1_TYPE == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
+ } else {
+ Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ }
+ } else if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
+ }
+ } while (0);
+
FREE_OP2();
FREE_OP1_VAR_PTR();
CHECK_EXCEPTION();
@@ -5716,7 +5771,6 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
FREE_UNFETCHED_OP2();
- FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
@@ -6520,14 +6574,15 @@ ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|T
HANDLE_EXCEPTION();
}
- offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ offset = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
-ZEND_VM_C_LABEL(isset_dim_obj_again):
if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
zval *value;
zend_string *str;
+ZEND_VM_C_LABEL(isset_dim_obj_array):
+ ht = Z_ARRVAL_P(container);
ZEND_VM_C_LABEL(isset_again):
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
@@ -6542,31 +6597,31 @@ ZEND_VM_C_LABEL(str_index_prop):
hval = Z_LVAL_P(offset);
ZEND_VM_C_LABEL(num_index_prop):
value = zend_hash_index_find(ht, hval);
+ } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+ offset = Z_REFVAL_P(offset);
+ ZEND_VM_C_GOTO(isset_again);
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ ZEND_VM_C_GOTO(num_index_prop);
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ ZEND_VM_C_GOTO(str_index_prop);
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ ZEND_VM_C_GOTO(num_index_prop);
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ ZEND_VM_C_GOTO(num_index_prop);
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ hval = Z_RES_HANDLE_P(offset);
+ ZEND_VM_C_GOTO(num_index_prop);
+ } else if (OP2_TYPE == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ ZEND_VM_C_GOTO(str_index_prop);
} else {
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- ZEND_VM_C_GOTO(num_index_prop);
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- ZEND_VM_C_GOTO(str_index_prop);
- case IS_FALSE:
- hval = 0;
- ZEND_VM_C_GOTO(num_index_prop);
- case IS_TRUE:
- hval = 1;
- ZEND_VM_C_GOTO(num_index_prop);
- case IS_RESOURCE:
- hval = Z_RES_HANDLE_P(offset);
- ZEND_VM_C_GOTO(num_index_prop);
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- ZEND_VM_C_GOTO(isset_again);
- default:
- zend_error(E_WARNING, "Illegal offset type in isset or empty");
- value = NULL;
- break;
- }
+ zend_error(E_WARNING, "Illegal offset type in isset or empty");
+ ZEND_VM_C_GOTO(isset_not_found);
}
if (opline->extended_value & ZEND_ISSET) {
@@ -6576,50 +6631,61 @@ ZEND_VM_C_LABEL(num_index_prop):
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value));
}
- } else if (OP1_TYPE == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ ZEND_VM_C_GOTO(isset_dim_obj_exit);
+ } else if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ ZEND_VM_C_GOTO(isset_dim_obj_array);
+ }
+ }
+
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ }
+
+ if (OP1_TYPE == IS_UNUSED ||
+ (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
- result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
- result = 0;
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
+ ZEND_VM_C_GOTO(isset_not_found);
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
- zval tmp;
+ zend_long lval;
- result = 0;
- if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ lval = Z_LVAL_P(offset);
+ZEND_VM_C_LABEL(isset_str_offset):
+ if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
+ if (opline->extended_value & ZEND_ISSET) {
+ result = 1;
+ } else {
+ result = (Z_STRVAL_P(container)[lval] == '0');
+ }
+ } else {
+ ZEND_VM_C_GOTO(isset_not_found);
+ }
+ } else {
if (OP2_TYPE & (IS_CV|IS_VAR)) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
- ZVAL_DUP(&tmp, offset);
- convert_to_long(&tmp);
- offset = &tmp;
- }
- }
- if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
- if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
- if ((opline->extended_value & ZEND_ISSET) ||
- Z_STRVAL_P(container)[offset->value.lval] != '0') {
- result = 1;
- }
+ lval = zval_get_long(offset);
+ ZEND_VM_C_GOTO(isset_str_offset);
}
+ ZEND_VM_C_GOTO(isset_not_found);
}
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
- } else if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- ZEND_VM_C_GOTO(isset_dim_obj_again);
} else {
+ZEND_VM_C_LABEL(isset_not_found):
result = ((opline->extended_value & ZEND_ISSET) == 0);
}
+ZEND_VM_C_LABEL(isset_dim_obj_exit):
FREE_OP2();
FREE_OP1();
ZEND_VM_SMART_BRANCH(result, 1);
@@ -6647,7 +6713,8 @@ ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
- if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (OP1_TYPE == IS_CONST ||
+ (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -6662,10 +6729,9 @@ ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|
ZEND_VM_C_LABEL(isset_no_object):
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
- result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
}
FREE_OP2();
@@ -7000,7 +7066,7 @@ ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMPVAR|CV, CONST|VAR)
zend_bool result;
SAVE_OPLINE();
- expr = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ expr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
ZEND_VM_C_LABEL(try_instanceof):
if (Z_TYPE_P(expr) == IS_OBJECT) {
@@ -7027,6 +7093,9 @@ ZEND_VM_C_LABEL(try_instanceof):
expr = Z_REFVAL_P(expr);
ZEND_VM_C_GOTO(try_instanceof);
} else {
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(expr, BP_VAR_R);
+ }
result = 0;
}
FREE_OP1();
@@ -7265,17 +7334,13 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
zend_op *brk_opline = &EX(func)->op_array.opcodes[EX(func)->op_array.brk_cont_array[i].brk];
if (brk_opline->opcode == ZEND_FREE) {
- if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
- zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
- }
+ zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
} else if (brk_opline->opcode == ZEND_FE_FREE) {
- if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
- zval *var = EX_VAR(brk_opline->op1.var);
- if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
- zend_hash_iterator_del(Z_FE_ITER_P(var));
- }
- zval_ptr_dtor_nogc(var);
+ zval *var = EX_VAR(brk_opline->op1.var);
+ if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
+ zend_hash_iterator_del(Z_FE_ITER_P(var));
}
+ zval_ptr_dtor_nogc(var);
} else if (brk_opline->opcode == ZEND_END_SILENCE) {
/* restore previous error_reporting value */
if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(brk_opline->op1.var)) != 0) {
@@ -7446,7 +7511,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
FREE_UNFETCHED_OP2();
FREE_UNFETCHED_OP1();
@@ -7463,7 +7528,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
if (OP1_TYPE != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -7473,11 +7538,10 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
value = GET_OP1_ZVAL_PTR(BP_VAR_R);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (OP1_TYPE != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (OP1_TYPE != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
@@ -7485,7 +7549,6 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
if (OP1_TYPE == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
FREE_UNFETCHED_OP2();
- FREE_OP1();
HANDLE_EXCEPTION();
}
@@ -7508,11 +7571,14 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
/* Consts, temporary variables and references need copying */
if (OP1_TYPE == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (OP1_TYPE == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
FREE_OP1_IF_VAR();
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -7533,11 +7599,14 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
/* Consts, temporary variables and references need copying */
if (OP2_TYPE == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (OP2_TYPE == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((OP2_TYPE == IS_VAR || OP2_TYPE == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
FREE_OP2_IF_VAR();
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -7742,11 +7811,12 @@ ZEND_VM_HANDLER(166, ZEND_POW, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- pow_function(EX_VAR(opline->result.var),
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ pow_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -7846,13 +7916,16 @@ ZEND_VM_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY)
zend_free_op free_op1;
SAVE_OPLINE();
- value = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
ZEND_VM_C_LABEL(try_strlen):
if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
} else {
zend_bool strict;
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+ value = GET_OP1_UNDEF_CV(value, BP_VAR_R);
+ }
if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
ZEND_VM_C_GOTO(try_strlen);
@@ -7890,7 +7963,7 @@ ZEND_VM_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|VAR|CV, ANY)
SAVE_OPLINE();
value = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) {
- if (UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+ if (OP1_TYPE != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
zend_class_entry *ce = Z_OBJCE_P(value);
if (UNEXPECTED(ce->name->len != sizeof("__PHP_Incomplete_Class") - 1) ||
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index e98f9dbf15..1ab12b7779 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -926,71 +926,67 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_
int arg_num;
SAVE_OPLINE();
- args = get_zval_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, BP_VAR_R);
+ args = get_zval_ptr_undef(opline->op1_type, opline->op1, execute_data, &free_op1, BP_VAR_R);
arg_num = ZEND_CALL_NUM_ARGS(EX(call)) + 1;
send_again:
- switch (Z_TYPE_P(args)) {
- case IS_ARRAY: {
- HashTable *ht = Z_ARRVAL_P(args);
- zval *arg, *top;
- zend_string *name;
-
- zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht));
-
- if (opline->op1_type != IS_CONST && opline->op1_type != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
- uint32_t i;
- int separate = 0;
-
- /* check if any of arguments are going to be passed by reference */
- for (i = 0; i < zend_hash_num_elements(ht); i++) {
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + i)) {
- separate = 1;
- break;
- }
- }
- if (separate) {
- zval_copy_ctor(args);
- ht = Z_ARRVAL_P(args);
+ if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) {
+ HashTable *ht = Z_ARRVAL_P(args);
+ zval *arg, *top;
+ zend_string *name;
+
+ zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht));
+
+ if (opline->op1_type != IS_CONST && opline->op1_type != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
+ uint32_t i;
+ int separate = 0;
+
+ /* check if any of arguments are going to be passed by reference */
+ for (i = 0; i < zend_hash_num_elements(ht); i++) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + i)) {
+ separate = 1;
+ break;
}
}
+ if (separate) {
+ zval_copy_ctor(args);
+ ht = Z_ARRVAL_P(args);
+ }
+ }
- ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) {
- if (name) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot unpack array with string keys");
- FREE_OP(free_op1);
- HANDLE_EXCEPTION();
- }
+ ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) {
+ if (name) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot unpack array with string keys");
+ FREE_OP(free_op1);
+ HANDLE_EXCEPTION();
+ }
- top = ZEND_CALL_ARG(EX(call), arg_num);
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
- if (!Z_IMMUTABLE_P(args)) {
- ZVAL_MAKE_REF(arg);
- Z_ADDREF_P(arg);
- ZVAL_REF(top, Z_REF_P(arg));
- } else {
- ZVAL_DUP(top, arg);
- }
- } else if (Z_ISREF_P(arg)) {
- ZVAL_COPY(top, Z_REFVAL_P(arg));
+ top = ZEND_CALL_ARG(EX(call), arg_num);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+ if (!Z_IMMUTABLE_P(args)) {
+ ZVAL_MAKE_REF(arg);
+ Z_ADDREF_P(arg);
+ ZVAL_REF(top, Z_REF_P(arg));
} else {
- ZVAL_COPY(top, arg);
+ ZVAL_DUP(top, arg);
}
+ } else if (Z_ISREF_P(arg)) {
+ ZVAL_COPY(top, Z_REFVAL_P(arg));
+ } else {
+ ZVAL_COPY(top, arg);
+ }
- ZEND_CALL_NUM_ARGS(EX(call))++;
- arg_num++;
- } ZEND_HASH_FOREACH_END();
+ ZEND_CALL_NUM_ARGS(EX(call))++;
+ arg_num++;
+ } ZEND_HASH_FOREACH_END();
- break;
- }
- case IS_OBJECT: {
- zend_class_entry *ce = Z_OBJCE_P(args);
- zend_object_iterator *iter;
+ } else if (EXPECTED(Z_TYPE_P(args) == IS_OBJECT)) {
+ zend_class_entry *ce = Z_OBJCE_P(args);
+ zend_object_iterator *iter;
- if (!ce || !ce->get_iterator) {
- zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
- break;
- }
+ if (!ce || !ce->get_iterator) {
+ zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
+ } else {
iter = ce->get_iterator(ce, args, 0);
if (UNEXPECTED(!iter)) {
@@ -1068,14 +1064,15 @@ send_again:
unpack_iter_dtor:
zend_iterator_dtor(iter);
- break;
}
- case IS_REFERENCE:
- args = Z_REFVAL_P(args);
- goto send_again;
- break;
- default:
- zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
+ } else if (EXPECTED(Z_ISREF_P(args))) {
+ args = Z_REFVAL_P(args);
+ goto send_again;
+ } else {
+ if (opline->op1_type == IS_CV && UNEXPECTED(Z_TYPE_P(args) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(args, BP_VAR_R);
+ }
+ zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
}
FREE_OP(free_op1);
@@ -1615,17 +1612,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(
zend_op *brk_opline = &EX(func)->op_array.opcodes[EX(func)->op_array.brk_cont_array[i].brk];
if (brk_opline->opcode == ZEND_FREE) {
- if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
- zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
- }
+ zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
} else if (brk_opline->opcode == ZEND_FE_FREE) {
- if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
- zval *var = EX_VAR(brk_opline->op1.var);
- if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
- zend_hash_iterator_del(Z_FE_ITER_P(var));
- }
- zval_ptr_dtor_nogc(var);
+ zval *var = EX_VAR(brk_opline->op1.var);
+ if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
+ zend_hash_iterator_del(Z_FE_ITER_P(var));
}
+ zval_ptr_dtor_nogc(var);
} else if (brk_opline->opcode == ZEND_END_SILENCE) {
/* restore previous error_reporting value */
if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(brk_opline->op1.var)) != 0) {
@@ -2004,6 +1997,9 @@ try_class_name:
class_name = Z_REFVAL_P(class_name);
goto try_class_name;
} else {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(class_name, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -2236,6 +2232,9 @@ try_function_name:
function_name = Z_REFVAL_P(function_name);
goto try_function_name;
} 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();
}
@@ -2352,31 +2351,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(Z
ZEND_VM_NEXT_OPCODE();
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BRK_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zend_brk_cont_element *el;
-
- SAVE_OPLINE();
- el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num,
- &EX(func)->op_array, execute_data);
- ZEND_VM_JMP(EX(func)->op_array.opcodes + el->brk);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zend_brk_cont_element *el;
-
- SAVE_OPLINE();
- el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num,
- &EX(func)->op_array, execute_data);
- ZEND_VM_JMP(EX(func)->op_array.opcodes + el->cont);
-}
-
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GOTO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- zend_op *brk_opline;
USE_OPLINE
zend_brk_cont_element *el;
@@ -2384,14 +2360,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GOTO_SPEC_CONST_HANDLER(ZEND_O
el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->extended_value,
&EX(func)->op_array, execute_data);
- brk_opline = EX(func)->op_array.opcodes + el->brk;
+ if (el->start >= 0) {
+ zend_op *brk_opline = EX(func)->op_array.opcodes + el->brk;
- if (brk_opline->opcode == ZEND_FREE) {
- if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
+ if (brk_opline->opcode == ZEND_FREE) {
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
- }
- } else if (brk_opline->opcode == ZEND_FE_FREE) {
- if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
+ } else if (brk_opline->opcode == ZEND_FE_FREE) {
zval *var = EX_VAR(brk_opline->op1.var);
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
@@ -2461,6 +2435,9 @@ try_class_name:
class_name = Z_REFVAL_P(class_name);
goto try_class_name;
} else {
+ if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(class_name, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -2486,7 +2463,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZE
ZEND_VM_NEXT_OPCODE();
} else {
- zval *class_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ zval *class_name = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
try_class_name:
if (IS_CV == IS_CONST) {
@@ -2504,6 +2481,9 @@ try_class_name:
class_name = Z_REFVAL_P(class_name);
goto try_class_name;
} else {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(class_name, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -2528,7 +2508,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HAND
uint32_t call_info = ZEND_CALL_NESTED_FUNCTION;
SAVE_OPLINE();
- function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ function_name = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
try_function_name:
if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
@@ -2708,6 +2688,9 @@ try_function_name:
function_name = Z_REFVAL_P(function_name);
goto try_function_name;
} 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();
}
@@ -2756,6 +2739,9 @@ try_class_name:
class_name = Z_REFVAL_P(class_name);
goto try_class_name;
} else {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(class_name, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -2961,6 +2947,9 @@ try_function_name:
function_name = Z_REFVAL_P(function_name);
goto try_function_name;
} else {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(function_name, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -3035,6 +3024,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_O
if (str->len != 0) {
zend_write(str->val, str->len);
+ } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(z, BP_VAR_R);
}
zend_string_release(str);
}
@@ -3252,15 +3243,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
SAVE_OPLINE();
retval_ptr = GET_OP1_UNDEF_CV(retval_ptr, BP_VAR_R);
- CHECK_EXCEPTION();
- }
-
- if (!EX(return_value)) {
+ if (EX(return_value)) {
+ ZVAL_NULL(EX(return_value));
+ }
+ } else if (!EX(return_value)) {
if (IS_CONST == IS_VAR || IS_CONST == 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));
- CHECK_EXCEPTION();
}
}
} else {
@@ -3326,7 +3316,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDL
if (IS_CONST == IS_VAR && UNEXPECTED(retval_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot return string offsets by reference");
-
HANDLE_EXCEPTION();
}
@@ -3417,6 +3406,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CONST_HANDLER(ZEND_
break;
}
}
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(value, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -3589,7 +3581,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_
if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) {
break;
}
- }
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(obj, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -3735,8 +3730,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_O
}
}
} else {
- ZVAL_COPY_VALUE(result, expr);
- zval_opt_copy_ctor(result);
+ ZVAL_COPY(result, expr);
convert_to_object(result);
}
}
@@ -3760,6 +3754,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN
ZVAL_UNDEF(&tmp_inc_filename);
if (Z_TYPE_P(inc_filename) != IS_STRING) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(inc_filename) == IS_UNDEF)) {
+ inc_filename = GET_OP1_UNDEF_CV(inc_filename, BP_VAR_R);
+ }
ZVAL_STR(&tmp_inc_filename, zval_get_string(inc_filename));
inc_filename = &tmp_inc_filename;
}
@@ -4382,6 +4379,9 @@ try_strlen:
} else {
zend_bool strict;
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+ value = GET_OP1_UNDEF_CV(value, BP_VAR_R);
+ }
if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
goto try_strlen;
@@ -4419,7 +4419,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CONST_HANDLER(
SAVE_OPLINE();
value = EX_CONSTANT(opline->op1);
if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) {
- if (UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+ if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
zend_class_entry *ce = Z_OBJCE_P(value);
if (UNEXPECTED(ce->name->len != sizeof("__PHP_Incomplete_Class") - 1) ||
@@ -4605,11 +4605,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CONST_HANDLER(Z
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- fast_div_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ fast_div_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -4659,11 +4660,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CONST_HANDLER(ZE
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_left_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ shift_left_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -4674,11 +4676,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_CONST_HANDLER(ZE
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_right_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ shift_right_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -4689,12 +4692,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CONST_HANDLE
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- concat_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+
+ do {
+ if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+ (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+ zend_string *op1_str = Z_STR_P(op1);
+ zend_string *op2_str = Z_STR_P(op2);
+ zend_string *str;
+
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+
+ break;
+ }
+ }
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+
+ break;
+ }
+ }
+ if (IS_CONST != IS_CONST && IS_CONST != IS_CV &&
+ !IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+ size_t len = op1_str->len;
+
+ str = zend_string_realloc(op1_str, len + op2_str->len, 0);
+ memcpy(str->val + len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ break;
+ } else {
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ }
+ } else {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ concat_function(EX_VAR(opline->result.var), op1, op2);
+ }
+ } while (0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -4704,12 +4753,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_CONST_
{
USE_OPLINE
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ result = fast_is_identical_function(op1, op2);
ZEND_VM_SMART_BRANCH(result, (IS_CONST|IS_CONST) & (IS_VAR|IS_TMP_VAR));
@@ -4724,12 +4774,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CO
{
USE_OPLINE
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ result = fast_is_not_identical_function(op1, op2);
ZEND_VM_SMART_BRANCH(result, (IS_CONST|IS_CONST) & (IS_VAR|IS_TMP_VAR));
@@ -4751,18 +4802,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CONST_HAND
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -4794,10 +4845,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CONST_HAND
} while (0);
SAVE_OPLINE();
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -4820,18 +4871,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -4863,10 +4914,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_
} while (0);
SAVE_OPLINE();
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -4984,12 +5035,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CONST_HAN
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2;
SAVE_OPLINE();
- compare_function(result,
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ compare_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -5000,11 +5051,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_CONST_HANDLER
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_or_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ bitwise_or_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -5015,11 +5067,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_CONST_HANDLE
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_and_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ bitwise_and_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -5030,11 +5083,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_CONST_HANDLE
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_xor_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ bitwise_xor_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -5045,11 +5099,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_CONST_HAND
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- boolean_xor_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -5074,6 +5129,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
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);
}
@@ -5289,7 +5347,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -5333,7 +5390,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_H
offset = EX_CONSTANT(opline->op2);
- if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CONST == IS_CONST ||
+ (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -5405,7 +5463,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_
offset = EX_CONSTANT(opline->op2);
- if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CONST == IS_CONST ||
+ (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -5486,7 +5545,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -5521,7 +5579,8 @@ try_fetch_list:
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
+ } 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);
@@ -5533,10 +5592,13 @@ try_fetch_list:
} else {
ZVAL_NULL(result);
}
- } else if (Z_TYPE_P(container) == IS_REFERENCE) {
+ } 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));
}
CHECK_EXCEPTION();
@@ -5552,27 +5614,59 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CONST_H
SAVE_OPLINE();
op1 = EX_CONSTANT(opline->op1);
- op2 = EX_CONSTANT(opline->op2);
if (IS_CONST == IS_CONST) {
op1_str = Z_STR_P(op1);
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ op1_str = zend_string_copy(Z_STR_P(op1));
} else {
- op1_str = zval_get_string(op1);
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ op1_str = _zval_get_string_func(op1);
}
+ op2 = EX_CONSTANT(opline->op2);
if (IS_CONST == IS_CONST) {
op2_str = Z_STR_P(op2);
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ op2_str = zend_string_copy(Z_STR_P(op2));
} else {
- op2_str = zval_get_string(op2);
- }
- str = zend_string_alloc(op1_str->len + op2_str->len, 0);
- memcpy(str->val, op1_str->val, op1_str->len);
- memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
- ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
- if (IS_CONST != IS_CONST) {
- zend_string_release(op1_str);
- }
- if (IS_CONST != IS_CONST) {
- zend_string_release(op2_str);
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ op2_str = _zval_get_string_func(op2);
}
+ do {
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ if (IS_CONST == IS_CONST) {
+ zend_string_addref(op2_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+ zend_string_release(op1_str);
+ break;
+ }
+ }
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ if (IS_CONST == IS_CONST) {
+ zend_string_addref(op1_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+ zend_string_release(op2_str);
+ break;
+ }
+ }
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ if (IS_CONST != IS_CONST) {
+ zend_string_release(op1_str);
+ }
+ if (IS_CONST != IS_CONST) {
+ zend_string_release(op2_str);
+ }
+ } while (0);
CHECK_EXCEPTION();
@@ -5604,6 +5698,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO
break;
}
}
+ 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();
}
@@ -5624,13 +5721,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO
if (IS_CONST != IS_UNUSED) {
do {
- if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
break;
}
}
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(object, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -5677,7 +5777,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
- } else if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+ } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+ /* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@@ -5736,6 +5837,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
function_name = EX_CONSTANT(opline->op2);
if (IS_CONST != IS_CONST) {
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ 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();
}
@@ -5889,18 +5993,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER(
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -5931,10 +6035,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER(
} while (0);
SAVE_OPLINE();
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -5952,7 +6056,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONS
SAVE_OPLINE();
if (IS_CONST == IS_UNUSED) {
zend_constant *c;
- zval *retval;
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
@@ -5978,67 +6081,80 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONS
} else {
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c);
}
- retval = EX_VAR(opline->result.var);
- ZVAL_COPY_VALUE(retval, &c->value);
- if (Z_OPT_COPYABLE_P(retval) || Z_OPT_REFCOUNTED_P(retval)) {
- if (Z_OPT_COPYABLE_P(retval)) {
- zval_copy_ctor_func(retval);
- } else {
- Z_ADDREF_P(retval);
- }
+#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;
- if (IS_CONST == IS_CONST) {
- if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
- value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
- ZVAL_DEREF(value);
- ZVAL_DUP(EX_VAR(opline->result.var), value);
- goto constant_fetch_end;
- } else if (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(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ do {
+ if (IS_CONST == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
+ value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
+ ZVAL_DEREF(value);
+#ifdef ZTS
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
+#endif
+ break;
+ } else if (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(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
+ if (UNEXPECTED(ce == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1)));
+ HANDLE_EXCEPTION();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
}
- if (UNEXPECTED(ce == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1)));
- 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;
}
- CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
- }
- } 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);
- ZVAL_DUP(EX_VAR(opline->result.var), value);
- goto constant_fetch_end;
}
- }
- 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 (IS_CONST == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value);
+ 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);
+ }
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value);
+ zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
+ HANDLE_EXCEPTION();
}
+ } while (0);
+#ifdef ZTS
+ if (ce->type == ZEND_INTERNAL_CLASS) {
ZVAL_DUP(EX_VAR(opline->result.var), value);
} else {
- zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
+ ZVAL_COPY(EX_VAR(opline->result.var), value);
}
+#else
+ ZVAL_COPY(EX_VAR(opline->result.var), value);
+#endif
}
-constant_fetch_end:
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -6050,11 +6166,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
SAVE_OPLINE();
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
-
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -6064,11 +6179,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
} else {
expr_ptr = EX_CONSTANT(opline->op1);
if (IS_CONST == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_CONST == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_CONST == IS_CV) {
@@ -6099,43 +6214,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if (IS_CONST != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if (IS_CONST != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
} else {
@@ -6210,6 +6323,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HAN
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;
}
@@ -6380,12 +6496,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON
offset = EX_CONSTANT(opline->op2);
-isset_dim_obj_again:
if (IS_CONST != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
zval *value;
zend_string *str;
+isset_dim_obj_array:
+ ht = Z_ARRVAL_P(container);
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
@@ -6400,31 +6517,31 @@ str_index_prop:
hval = Z_LVAL_P(offset);
num_index_prop:
value = zend_hash_index_find(ht, hval);
- } else {
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index_prop;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index_prop;
- case IS_FALSE:
- hval = 0;
- goto num_index_prop;
- case IS_TRUE:
- hval = 1;
- goto num_index_prop;
- case IS_RESOURCE:
- hval = Z_RES_HANDLE_P(offset);
- goto num_index_prop;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto isset_again;
- default:
- zend_error(E_WARNING, "Illegal offset type in isset or empty");
- value = NULL;
- break;
- }
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+ offset = Z_REFVAL_P(offset);
+ goto isset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ hval = Z_RES_HANDLE_P(offset);
+ goto num_index_prop;
+ } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type in isset or empty");
+ goto isset_not_found;
}
if (opline->extended_value & ZEND_ISSET) {
@@ -6434,50 +6551,62 @@ num_index_prop:
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value));
}
- } else if (IS_CONST == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ goto isset_dim_obj_exit;
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto isset_dim_obj_array;
+ }
+ }
+
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ }
+
+ if (IS_CONST == IS_UNUSED ||
+ (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
- result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
- result = 0;
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
+ goto isset_not_found;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
- zval tmp;
+ zend_long lval;
- result = 0;
- if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ lval = Z_LVAL_P(offset);
+isset_str_offset:
+ if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
+ if (opline->extended_value & ZEND_ISSET) {
+ result = 1;
+ } else {
+ result = (Z_STRVAL_P(container)[lval] == '0');
+ }
+ } else {
+ goto isset_not_found;
+ }
+ } else {
if (IS_CONST & (IS_CV|IS_VAR)) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
- ZVAL_DUP(&tmp, offset);
- convert_to_long(&tmp);
- offset = &tmp;
- }
- }
- if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
- if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
- if ((opline->extended_value & ZEND_ISSET) ||
- Z_STRVAL_P(container)[offset->value.lval] != '0') {
- result = 1;
- }
+ lval = zval_get_long(offset);
+ goto isset_str_offset;
}
+ goto isset_not_found;
}
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
- } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto isset_dim_obj_again;
} else {
+isset_not_found:
result = ((opline->extended_value & ZEND_ISSET) == 0);
}
+isset_dim_obj_exit:
+
ZEND_VM_SMART_BRANCH(result, 1);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
@@ -6504,7 +6633,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CO
offset = EX_CONSTANT(opline->op2);
- if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CONST == IS_CONST ||
+ (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -6519,10 +6649,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CO
isset_no_object:
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
- result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
}
@@ -6576,7 +6705,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
@@ -6593,7 +6722,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER
if (IS_CONST != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -6603,11 +6732,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER
value = EX_CONSTANT(opline->op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_CONST != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -6615,7 +6743,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER
if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
-
HANDLE_EXCEPTION();
}
@@ -6637,11 +6764,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER
/* Consts, temporary variables and references need copying */
if (IS_CONST == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -6662,11 +6792,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER
/* Consts, temporary variables and references need copying */
if (IS_CONST == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -6710,11 +6843,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_CONST_HANDLER(Z
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- pow_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ pow_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -6725,12 +6859,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_TMP_HA
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_CONST|IS_TMP_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -6745,12 +6880,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_TM
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_CONST|IS_TMP_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -6768,7 +6904,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
@@ -6785,7 +6921,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z
if (IS_CONST != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -6795,11 +6931,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z
value = EX_CONSTANT(opline->op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_CONST != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -6807,7 +6942,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z
if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-
HANDLE_EXCEPTION();
}
@@ -6829,11 +6963,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z
/* Consts, temporary variables and references need copying */
if (IS_CONST == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -6854,11 +6991,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z
/* Consts, temporary variables and references need copying */
if (IS_TMP_VAR == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -6902,12 +7042,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_VAR_HA
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_CONST|IS_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -6922,12 +7063,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VA
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_CONST|IS_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -6956,6 +7098,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
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);
}
@@ -7156,6 +7301,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDL
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;
}
@@ -7313,7 +7461,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(Z
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
@@ -7330,7 +7478,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(Z
if (IS_CONST != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -7340,11 +7488,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(Z
value = EX_CONSTANT(opline->op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_CONST != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -7352,7 +7499,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(Z
if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-
HANDLE_EXCEPTION();
}
@@ -7374,11 +7520,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(Z
/* Consts, temporary variables and references need copying */
if (IS_CONST == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -7399,11 +7548,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(Z
/* Consts, temporary variables and references need copying */
if (IS_VAR == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
zval_ptr_dtor_nogc(free_op2);
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -7461,6 +7613,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
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);
}
@@ -7646,7 +7801,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
-
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED);
@@ -7715,6 +7869,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
function_name = NULL;
if (IS_UNUSED != IS_CONST) {
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ 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();
}
@@ -7844,6 +8001,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_
}
}
zend_verify_return_type(EX(func), retval_ptr);
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ }
#endif
}
CHECK_EXCEPTION();
@@ -7858,11 +8019,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_U
SAVE_OPLINE();
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
-
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -7872,11 +8032,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_U
} else {
expr_ptr = EX_CONSTANT(opline->op1);
if (IS_CONST == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_CONST == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_CONST == IS_CV) {
@@ -7907,43 +8067,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_U
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if (IS_UNUSED != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if (IS_UNUSED != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
} else {
@@ -8018,6 +8176,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HA
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;
}
@@ -8198,7 +8359,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
@@ -8215,7 +8376,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE
if (IS_CONST != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -8225,11 +8386,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE
value = EX_CONSTANT(opline->op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_CONST != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -8237,7 +8397,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE
if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
-
HANDLE_EXCEPTION();
}
@@ -8259,11 +8418,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE
/* Consts, temporary variables and references need copying */
if (IS_CONST == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -8284,11 +8446,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE
/* Consts, temporary variables and references need copying */
if (IS_UNUSED == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -8467,11 +8632,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CV_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- fast_div_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ fast_div_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -8521,11 +8687,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CV_HANDLER(ZEND_
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_left_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ shift_left_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -8536,11 +8703,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_CV_HANDLER(ZEND_
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_right_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ shift_right_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -8551,12 +8719,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- concat_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+
+ do {
+ if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+ (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+ zend_string *op1_str = Z_STR_P(op1);
+ zend_string *op2_str = Z_STR_P(op2);
+ zend_string *str;
+
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+
+ break;
+ }
+ }
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+
+ break;
+ }
+ }
+ if (IS_CONST != IS_CONST && IS_CONST != IS_CV &&
+ !IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+ size_t len = op1_str->len;
+
+ str = zend_string_realloc(op1_str, len + op2_str->len, 0);
+ memcpy(str->val + len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ break;
+ } else {
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ }
+ } else {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ concat_function(EX_VAR(opline->result.var), op1, op2);
+ }
+ } while (0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -8566,12 +8780,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_CV_HAN
{
USE_OPLINE
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ result = fast_is_identical_function(op1, op2);
ZEND_VM_SMART_BRANCH(result, (IS_CONST|IS_CV) & (IS_VAR|IS_TMP_VAR));
@@ -8586,12 +8801,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CV
{
USE_OPLINE
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ result = fast_is_not_identical_function(op1, op2);
ZEND_VM_SMART_BRANCH(result, (IS_CONST|IS_CV) & (IS_VAR|IS_TMP_VAR));
@@ -8613,18 +8829,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CV_HANDLER
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -8656,10 +8872,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CV_HANDLER
} while (0);
SAVE_OPLINE();
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -8682,18 +8898,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CV_HAN
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -8725,10 +8941,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CV_HAN
} while (0);
SAVE_OPLINE();
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -8846,12 +9062,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CV_HANDLE
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2;
SAVE_OPLINE();
- compare_function(result,
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ compare_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -8862,11 +9078,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_CV_HANDLER(ZE
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_or_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ bitwise_or_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -8877,11 +9094,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_CV_HANDLER(Z
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_and_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ bitwise_and_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -8892,11 +9110,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_CV_HANDLER(Z
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_xor_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ bitwise_xor_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -8907,11 +9126,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_CV_HANDLER
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- boolean_xor_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -8967,7 +9187,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -9011,7 +9230,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HAND
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CONST == IS_CONST ||
+ (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -9083,7 +9303,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HAN
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CONST == IS_CONST ||
+ (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -9164,7 +9385,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -9189,27 +9409,59 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND
SAVE_OPLINE();
op1 = EX_CONSTANT(opline->op1);
- op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
if (IS_CONST == IS_CONST) {
op1_str = Z_STR_P(op1);
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ op1_str = zend_string_copy(Z_STR_P(op1));
} else {
- op1_str = zval_get_string(op1);
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ op1_str = _zval_get_string_func(op1);
}
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
if (IS_CV == IS_CONST) {
op2_str = Z_STR_P(op2);
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ op2_str = zend_string_copy(Z_STR_P(op2));
} else {
- op2_str = zval_get_string(op2);
- }
- str = zend_string_alloc(op1_str->len + op2_str->len, 0);
- memcpy(str->val, op1_str->val, op1_str->len);
- memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
- ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
- if (IS_CONST != IS_CONST) {
- zend_string_release(op1_str);
- }
- if (IS_CV != IS_CONST) {
- zend_string_release(op2_str);
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ op2_str = _zval_get_string_func(op2);
}
+ do {
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ if (IS_CV == IS_CONST) {
+ zend_string_addref(op2_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+ zend_string_release(op1_str);
+ break;
+ }
+ }
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ if (IS_CONST == IS_CONST) {
+ zend_string_addref(op1_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+ zend_string_release(op2_str);
+ break;
+ }
+ }
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ if (IS_CONST != IS_CONST) {
+ zend_string_release(op1_str);
+ }
+ if (IS_CV != IS_CONST) {
+ zend_string_release(op2_str);
+ }
+ } while (0);
CHECK_EXCEPTION();
@@ -9230,7 +9482,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV
SAVE_OPLINE();
- function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ function_name = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
@@ -9241,6 +9493,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV
break;
}
}
+ 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();
}
@@ -9261,13 +9516,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV
if (IS_CONST != IS_UNUSED) {
do {
- if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
break;
}
}
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(object, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -9314,7 +9572,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
- } else if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+ } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+ /* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@@ -9370,9 +9629,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
} else if (IS_CV != IS_UNUSED) {
- function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ 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)) {
+ 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();
}
@@ -9577,18 +9839,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEN
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -9619,10 +9881,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEN
} while (0);
SAVE_OPLINE();
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -9641,11 +9903,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
SAVE_OPLINE();
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
-
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -9655,11 +9916,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
} else {
expr_ptr = EX_CONSTANT(opline->op1);
if (IS_CONST == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_CONST == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_CONST == IS_CV) {
@@ -9685,48 +9946,46 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
if (IS_CV != IS_UNUSED) {
- zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ zval *offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
zend_string *str;
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if (IS_CV != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if (IS_CV != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
} else {
@@ -9785,14 +10044,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON
HANDLE_EXCEPTION();
}
- offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
-isset_dim_obj_again:
if (IS_CONST != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
zval *value;
zend_string *str;
+isset_dim_obj_array:
+ ht = Z_ARRVAL_P(container);
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
@@ -9807,31 +10067,31 @@ str_index_prop:
hval = Z_LVAL_P(offset);
num_index_prop:
value = zend_hash_index_find(ht, hval);
- } else {
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index_prop;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index_prop;
- case IS_FALSE:
- hval = 0;
- goto num_index_prop;
- case IS_TRUE:
- hval = 1;
- goto num_index_prop;
- case IS_RESOURCE:
- hval = Z_RES_HANDLE_P(offset);
- goto num_index_prop;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto isset_again;
- default:
- zend_error(E_WARNING, "Illegal offset type in isset or empty");
- value = NULL;
- break;
- }
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+ offset = Z_REFVAL_P(offset);
+ goto isset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ hval = Z_RES_HANDLE_P(offset);
+ goto num_index_prop;
+ } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type in isset or empty");
+ goto isset_not_found;
}
if (opline->extended_value & ZEND_ISSET) {
@@ -9841,50 +10101,62 @@ num_index_prop:
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value));
}
- } else if (IS_CONST == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ goto isset_dim_obj_exit;
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto isset_dim_obj_array;
+ }
+ }
+
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ }
+
+ if (IS_CONST == IS_UNUSED ||
+ (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
- result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
- result = 0;
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
+ goto isset_not_found;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
- zval tmp;
+ zend_long lval;
- result = 0;
- if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ lval = Z_LVAL_P(offset);
+isset_str_offset:
+ if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
+ if (opline->extended_value & ZEND_ISSET) {
+ result = 1;
+ } else {
+ result = (Z_STRVAL_P(container)[lval] == '0');
+ }
+ } else {
+ goto isset_not_found;
+ }
+ } else {
if (IS_CV & (IS_CV|IS_VAR)) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
- ZVAL_DUP(&tmp, offset);
- convert_to_long(&tmp);
- offset = &tmp;
+ lval = zval_get_long(offset);
+ goto isset_str_offset;
}
+ goto isset_not_found;
}
- if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
- if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
- if ((opline->extended_value & ZEND_ISSET) ||
- Z_STRVAL_P(container)[offset->value.lval] != '0') {
- result = 1;
- }
- }
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
- } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto isset_dim_obj_again;
} else {
+isset_not_found:
result = ((opline->extended_value & ZEND_ISSET) == 0);
}
+isset_dim_obj_exit:
+
ZEND_VM_SMART_BRANCH(result, 1);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
@@ -9911,7 +10183,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CO
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CONST == IS_CONST ||
+ (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -9926,10 +10199,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CO
isset_no_object:
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
- result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
}
@@ -9946,7 +10218,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
@@ -9963,7 +10235,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE
if (IS_CONST != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -9973,11 +10245,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE
value = EX_CONSTANT(opline->op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_CONST != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -9985,7 +10256,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE
if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
-
HANDLE_EXCEPTION();
}
@@ -10007,11 +10277,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE
/* Consts, temporary variables and references need copying */
if (IS_CONST == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -10032,11 +10305,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE
/* Consts, temporary variables and references need copying */
if (IS_CV == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -10080,11 +10356,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_CV_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- pow_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ pow_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -10230,11 +10507,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER(
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- fast_div_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ fast_div_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -10284,11 +10562,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_TMPVAR_HANDLER(Z
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_left_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ shift_left_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -10299,11 +10578,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_TMPVAR_HANDLER(Z
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_right_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ shift_right_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -10314,12 +10594,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- concat_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+
+ do {
+ if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+ ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+ zend_string *op1_str = Z_STR_P(op1);
+ zend_string *op2_str = Z_STR_P(op2);
+ zend_string *str;
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+
+ break;
+ }
+ }
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+
+ break;
+ }
+ }
+ if (IS_CONST != IS_CONST && IS_CONST != IS_CV &&
+ !IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+ size_t len = op1_str->len;
+
+ str = zend_string_realloc(op1_str, len + op2_str->len, 0);
+ memcpy(str->val + len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ break;
+ } else {
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ }
+ } else {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ concat_function(EX_VAR(opline->result.var), op1, op2);
+ }
+
+ } while (0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -10336,18 +10662,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_TMPVAR_HAN
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -10379,10 +10705,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_TMPVAR_HAN
} while (0);
SAVE_OPLINE();
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -10405,18 +10731,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_TMPVAR
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -10448,10 +10774,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_TMPVAR
} while (0);
SAVE_OPLINE();
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -10569,12 +10895,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HA
{
USE_OPLINE
zend_free_op free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2;
SAVE_OPLINE();
- compare_function(result,
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ compare_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -10585,11 +10911,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_TMPVAR_HANDLE
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_or_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ bitwise_or_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -10600,11 +10927,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_TMPVAR_HANDL
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_and_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ bitwise_and_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -10615,11 +10943,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_TMPVAR_HANDL
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_xor_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ bitwise_xor_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -10630,11 +10959,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_TMPVAR_HAN
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- boolean_xor_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -10690,7 +11020,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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));
@@ -10734,7 +11063,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CONST == IS_CONST ||
+ (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -10807,7 +11137,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CONST == IS_CONST ||
+ (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -10889,7 +11220,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -10914,27 +11244,59 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
SAVE_OPLINE();
op1 = EX_CONSTANT(opline->op1);
- op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
if (IS_CONST == IS_CONST) {
op1_str = Z_STR_P(op1);
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ op1_str = zend_string_copy(Z_STR_P(op1));
} else {
- op1_str = zval_get_string(op1);
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ op1_str = _zval_get_string_func(op1);
}
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
op2_str = Z_STR_P(op2);
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ op2_str = zend_string_copy(Z_STR_P(op2));
} else {
- op2_str = zval_get_string(op2);
- }
- str = zend_string_alloc(op1_str->len + op2_str->len, 0);
- memcpy(str->val, op1_str->val, op1_str->len);
- memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
- ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
- if (IS_CONST != IS_CONST) {
- zend_string_release(op1_str);
- }
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- zend_string_release(op2_str);
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ op2_str = _zval_get_string_func(op2);
}
+ do {
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+ zend_string_addref(op2_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+ zend_string_release(op1_str);
+ break;
+ }
+ }
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ if (IS_CONST == IS_CONST) {
+ zend_string_addref(op1_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+ zend_string_release(op2_str);
+ break;
+ }
+ }
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ if (IS_CONST != IS_CONST) {
+ zend_string_release(op1_str);
+ }
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ zend_string_release(op2_str);
+ }
+ } while (0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -10966,6 +11328,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM
break;
}
}
+ 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();
}
@@ -10986,13 +11351,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM
if (IS_CONST != IS_UNUSED) {
do {
- if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
break;
}
}
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(object, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -11039,7 +11407,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
- } else if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+ } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+ /* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@@ -11099,6 +11468,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
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)) {
+ 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();
}
@@ -11253,18 +11625,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -11295,10 +11667,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER
} while (0);
SAVE_OPLINE();
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -11317,11 +11689,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_T
SAVE_OPLINE();
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
-
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -11331,11 +11702,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_T
} else {
expr_ptr = EX_CONSTANT(opline->op1);
if (IS_CONST == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_CONST == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_CONST == IS_CV) {
@@ -11366,43 +11737,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_T
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
zval_ptr_dtor_nogc(free_op2);
} else {
@@ -11463,12 +11832,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
-isset_dim_obj_again:
if (IS_CONST != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
zval *value;
zend_string *str;
+isset_dim_obj_array:
+ ht = Z_ARRVAL_P(container);
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
@@ -11483,31 +11853,31 @@ str_index_prop:
hval = Z_LVAL_P(offset);
num_index_prop:
value = zend_hash_index_find(ht, hval);
- } else {
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index_prop;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index_prop;
- case IS_FALSE:
- hval = 0;
- goto num_index_prop;
- case IS_TRUE:
- hval = 1;
- goto num_index_prop;
- case IS_RESOURCE:
- hval = Z_RES_HANDLE_P(offset);
- goto num_index_prop;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto isset_again;
- default:
- zend_error(E_WARNING, "Illegal offset type in isset or empty");
- value = NULL;
- break;
- }
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+ offset = Z_REFVAL_P(offset);
+ goto isset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ hval = Z_RES_HANDLE_P(offset);
+ goto num_index_prop;
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type in isset or empty");
+ goto isset_not_found;
}
if (opline->extended_value & ZEND_ISSET) {
@@ -11517,50 +11887,61 @@ num_index_prop:
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value));
}
- } else if (IS_CONST == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ goto isset_dim_obj_exit;
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto isset_dim_obj_array;
+ }
+ }
+
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ }
+
+ if (IS_CONST == IS_UNUSED ||
+ (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
- result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
- result = 0;
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
+ goto isset_not_found;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
- zval tmp;
+ zend_long lval;
- result = 0;
- if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ lval = Z_LVAL_P(offset);
+isset_str_offset:
+ if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
+ if (opline->extended_value & ZEND_ISSET) {
+ result = 1;
+ } else {
+ result = (Z_STRVAL_P(container)[lval] == '0');
+ }
+ } else {
+ goto isset_not_found;
+ }
+ } else {
if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
- ZVAL_DUP(&tmp, offset);
- convert_to_long(&tmp);
- offset = &tmp;
- }
- }
- if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
- if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
- if ((opline->extended_value & ZEND_ISSET) ||
- Z_STRVAL_P(container)[offset->value.lval] != '0') {
- result = 1;
- }
+ lval = zval_get_long(offset);
+ goto isset_str_offset;
}
+ goto isset_not_found;
}
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
- } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto isset_dim_obj_again;
} else {
+isset_not_found:
result = ((opline->extended_value & ZEND_ISSET) == 0);
}
+isset_dim_obj_exit:
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, 1);
@@ -11588,7 +11969,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CO
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CONST == IS_CONST ||
+ (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -11603,10 +11985,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CO
isset_no_object:
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
- result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
}
zval_ptr_dtor_nogc(free_op2);
@@ -11621,11 +12002,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_TMPVAR_HANDLER(
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- pow_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ pow_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -11642,15 +12024,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_O
if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
SAVE_OPLINE();
retval_ptr = GET_OP1_UNDEF_CV(retval_ptr, BP_VAR_R);
- CHECK_EXCEPTION();
- }
-
- if (!EX(return_value)) {
+ if (EX(return_value)) {
+ ZVAL_NULL(EX(return_value));
+ }
+ } else if (!EX(return_value)) {
if (IS_TMP_VAR == IS_VAR || IS_TMP_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));
- CHECK_EXCEPTION();
}
}
} else {
@@ -11716,7 +12097,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(retval_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot return string offsets by reference");
-
HANDLE_EXCEPTION();
}
@@ -11807,6 +12187,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OP
break;
}
}
+ if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(value, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -11966,8 +12349,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC
}
}
} else {
- ZVAL_COPY_VALUE(result, expr);
- zval_opt_copy_ctor(result);
+ ZVAL_COPY(result, expr);
convert_to_object(result);
}
}
@@ -12467,7 +12849,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_TMP_HANDLER(ZE
SAVE_OPLINE();
value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) {
- if (UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+ if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
zend_class_entry *ce = Z_OBJCE_P(value);
if (UNEXPECTED(ce->name->len != sizeof("__PHP_Incomplete_Class") - 1) ||
@@ -12498,12 +12880,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HA
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_SMART_BRANCH(result, (IS_TMP_VAR|IS_CONST) & (IS_VAR|IS_TMP_VAR));
@@ -12518,12 +12901,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONS
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_SMART_BRANCH(result, (IS_TMP_VAR|IS_CONST) & (IS_VAR|IS_TMP_VAR));
@@ -12553,7 +12937,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -12597,7 +12980,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HAN
offset = EX_CONSTANT(opline->op2);
- if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_TMP_VAR == IS_CONST ||
+ (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -12678,7 +13062,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -12707,11 +13090,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLE
var = EX_CONSTANT(opline->op2);
rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
} else {
- SAVE_OPLINE();
var = EX_CONSTANT(opline->op2);
- rope[opline->extended_value] = zval_get_string(var);
+ if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+ if (IS_CONST == IS_CV) {
+ rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+ } else {
+ rope[opline->extended_value] = Z_STR_P(var);
+ }
+ } else {
+ SAVE_OPLINE();
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(var, BP_VAR_R);
+ }
+ rope[opline->extended_value] = _zval_get_string_func(var);
- CHECK_EXCEPTION();
+ CHECK_EXCEPTION();
+ }
}
ZEND_VM_NEXT_OPCODE();
}
@@ -12731,11 +13125,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CONST_HANDLE
var = EX_CONSTANT(opline->op2);
rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
} else {
- SAVE_OPLINE();
var = EX_CONSTANT(opline->op2);
- rope[opline->extended_value] = zval_get_string(var);
+ if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+ if (IS_CONST == IS_CV) {
+ rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+ } else {
+ rope[opline->extended_value] = Z_STR_P(var);
+ }
+ } else {
+ SAVE_OPLINE();
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(var, BP_VAR_R);
+ }
+ rope[opline->extended_value] = _zval_get_string_func(var);
- CHECK_EXCEPTION();
+ CHECK_EXCEPTION();
+ }
}
for (i = 0; i <= opline->extended_value; i++) {
len += rope[i]->len;
@@ -12761,11 +13166,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CON
SAVE_OPLINE();
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
-
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -12775,11 +13179,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CON
} else {
expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
if (IS_TMP_VAR == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_TMP_VAR == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_TMP_VAR == IS_CV) {
@@ -12810,43 +13214,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CON
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if (IS_CONST != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if (IS_CONST != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
} else {
@@ -12894,7 +13296,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -12911,7 +13313,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -12921,11 +13323,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z
value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_TMP_VAR != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_TMP_VAR != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -12933,7 +13334,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
- zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -12955,11 +13355,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z
/* Consts, temporary variables and references need copying */
if (IS_TMP_VAR == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -12980,11 +13383,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z
/* Consts, temporary variables and references need copying */
if (IS_CONST == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -13028,12 +13434,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HAND
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_TMP_VAR|IS_TMP_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -13048,12 +13455,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_TMP_VAR|IS_TMP_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -13071,7 +13479,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEN
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -13088,7 +13496,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEN
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -13098,11 +13506,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEN
value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_TMP_VAR != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_TMP_VAR != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -13110,7 +13517,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEN
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
- zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -13132,11 +13538,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEN
/* Consts, temporary variables and references need copying */
if (IS_TMP_VAR == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -13157,11 +13566,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEN
/* Consts, temporary variables and references need copying */
if (IS_TMP_VAR == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -13205,12 +13617,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_VAR_HAND
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -13225,12 +13638,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -13248,7 +13662,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEN
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -13265,7 +13679,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEN
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -13275,11 +13689,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEN
value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_TMP_VAR != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_TMP_VAR != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -13287,7 +13700,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEN
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
- zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -13309,11 +13721,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEN
/* Consts, temporary variables and references need copying */
if (IS_TMP_VAR == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -13334,11 +13749,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEN
/* Consts, temporary variables and references need copying */
if (IS_VAR == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
zval_ptr_dtor_nogc(free_op2);
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -13397,7 +13815,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UN
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
-
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED);
@@ -13465,6 +13882,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN
}
}
zend_verify_return_type(EX(func), retval_ptr);
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zval_ptr_dtor_nogc(free_op1);
+ }
#endif
}
CHECK_EXCEPTION();
@@ -13479,11 +13900,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNU
SAVE_OPLINE();
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
-
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -13493,11 +13913,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNU
} else {
expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
if (IS_TMP_VAR == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_TMP_VAR == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_TMP_VAR == IS_CV) {
@@ -13528,43 +13948,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNU
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if (IS_UNUSED != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if (IS_UNUSED != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
} else {
@@ -13612,7 +14030,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -13629,7 +14047,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -13639,11 +14057,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(
value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_TMP_VAR != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_TMP_VAR != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -13651,7 +14068,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
- zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -13673,11 +14089,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(
/* Consts, temporary variables and references need copying */
if (IS_TMP_VAR == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -13698,11 +14117,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(
/* Consts, temporary variables and references need copying */
if (IS_UNUSED == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -13746,12 +14168,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CV_HANDL
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_SMART_BRANCH(result, (IS_TMP_VAR|IS_CV) & (IS_VAR|IS_TMP_VAR));
@@ -13766,12 +14189,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV_H
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_SMART_BRANCH(result, (IS_TMP_VAR|IS_CV) & (IS_VAR|IS_TMP_VAR));
@@ -13801,7 +14225,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -13845,7 +14268,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLE
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_TMP_VAR == IS_CONST ||
+ (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -13926,7 +14350,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -13955,11 +14378,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER(Z
var = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
} else {
- SAVE_OPLINE();
- var = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- rope[opline->extended_value] = zval_get_string(var);
+ var = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+ if (IS_CV == IS_CV) {
+ rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+ } else {
+ rope[opline->extended_value] = Z_STR_P(var);
+ }
+ } else {
+ SAVE_OPLINE();
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(var, BP_VAR_R);
+ }
+ rope[opline->extended_value] = _zval_get_string_func(var);
- CHECK_EXCEPTION();
+ CHECK_EXCEPTION();
+ }
}
ZEND_VM_NEXT_OPCODE();
}
@@ -13979,11 +14413,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(Z
var = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
} else {
- SAVE_OPLINE();
- var = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- rope[opline->extended_value] = zval_get_string(var);
+ var = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+ if (IS_CV == IS_CV) {
+ rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+ } else {
+ rope[opline->extended_value] = Z_STR_P(var);
+ }
+ } else {
+ SAVE_OPLINE();
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(var, BP_VAR_R);
+ }
+ rope[opline->extended_value] = _zval_get_string_func(var);
- CHECK_EXCEPTION();
+ CHECK_EXCEPTION();
+ }
}
for (i = 0; i <= opline->extended_value; i++) {
len += rope[i]->len;
@@ -14009,11 +14454,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_
SAVE_OPLINE();
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
-
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -14023,11 +14467,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_
} else {
expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
if (IS_TMP_VAR == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_TMP_VAR == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_TMP_VAR == IS_CV) {
@@ -14053,48 +14497,46 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_
if (IS_CV != IS_UNUSED) {
- zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ zval *offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
zend_string *str;
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if (IS_CV != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if (IS_CV != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
} else {
@@ -14142,7 +14584,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -14159,7 +14601,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -14169,11 +14611,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND
value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_TMP_VAR != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_TMP_VAR != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -14181,7 +14622,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
- zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -14203,11 +14643,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND
/* Consts, temporary variables and references need copying */
if (IS_TMP_VAR == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -14228,11 +14671,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND
/* Consts, temporary variables and references need copying */
if (IS_CV == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -14291,7 +14737,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TM
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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));
@@ -14335,7 +14780,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR_HA
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_TMP_VAR == IS_CONST ||
+ (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -14417,7 +14863,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TM
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -14446,11 +14891,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDL
var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
} else {
- SAVE_OPLINE();
var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- rope[opline->extended_value] = zval_get_string(var);
- zval_ptr_dtor_nogc(free_op2);
- CHECK_EXCEPTION();
+ if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
+ rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+ } else {
+ rope[opline->extended_value] = Z_STR_P(var);
+ }
+ } else {
+ SAVE_OPLINE();
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(var, BP_VAR_R);
+ }
+ rope[opline->extended_value] = _zval_get_string_func(var);
+ zval_ptr_dtor_nogc(free_op2);
+ CHECK_EXCEPTION();
+ }
}
ZEND_VM_NEXT_OPCODE();
}
@@ -14470,11 +14926,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDL
var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
} else {
- SAVE_OPLINE();
var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- rope[opline->extended_value] = zval_get_string(var);
- zval_ptr_dtor_nogc(free_op2);
- CHECK_EXCEPTION();
+ if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
+ rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+ } else {
+ rope[opline->extended_value] = Z_STR_P(var);
+ }
+ } else {
+ SAVE_OPLINE();
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(var, BP_VAR_R);
+ }
+ rope[opline->extended_value] = _zval_get_string_func(var);
+ zval_ptr_dtor_nogc(free_op2);
+ CHECK_EXCEPTION();
+ }
}
for (i = 0; i <= opline->extended_value; i++) {
len += rope[i]->len;
@@ -14500,11 +14967,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP
SAVE_OPLINE();
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
-
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -14514,11 +14980,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP
} else {
expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
if (IS_TMP_VAR == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_TMP_VAR == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_TMP_VAR == IS_CV) {
@@ -14549,43 +15015,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
zval_ptr_dtor_nogc(free_op2);
} else {
@@ -14637,7 +15101,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -14685,7 +15148,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -14733,7 +15195,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -14774,7 +15235,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -14814,15 +15274,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_O
if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
SAVE_OPLINE();
retval_ptr = GET_OP1_UNDEF_CV(retval_ptr, BP_VAR_R);
- CHECK_EXCEPTION();
- }
-
- if (!EX(return_value)) {
+ if (EX(return_value)) {
+ ZVAL_NULL(EX(return_value));
+ }
+ } else if (!EX(return_value)) {
if (IS_VAR == 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));
- CHECK_EXCEPTION();
}
}
} else {
@@ -14888,7 +15347,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER
if (IS_VAR == IS_VAR && UNEXPECTED(retval_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot return string offsets by reference");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -14980,6 +15438,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OP
break;
}
}
+ if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(value, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -15089,7 +15550,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND
if (IS_VAR == IS_VAR && UNEXPECTED(varptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Only variables can be passed by reference");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -15365,8 +15825,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC
}
}
} else {
- ZVAL_COPY_VALUE(result, expr);
- zval_opt_copy_ctor(result);
+ ZVAL_COPY(result, expr);
convert_to_object(result);
}
}
@@ -16238,7 +16697,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_VAR_HANDLER(ZE
SAVE_OPLINE();
value = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) {
- if (UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+ if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
zend_class_entry *ce = Z_OBJCE_P(value);
if (UNEXPECTED(ce->name->len != sizeof("__PHP_Incomplete_Class") - 1) ||
@@ -16269,12 +16728,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HA
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_SMART_BRANCH(result, (IS_VAR|IS_CONST) & (IS_VAR|IS_TMP_VAR));
@@ -16289,12 +16749,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONS
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_SMART_BRANCH(result, (IS_VAR|IS_CONST) & (IS_VAR|IS_TMP_VAR));
@@ -16330,7 +16791,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -16360,42 +16820,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval *z;
- zval rv, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- if (Z_OBJ_HT(obj)->read_property &&
- (z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
- if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- zptr = z;
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- binary_op(z, z, value);
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- zval_ptr_dtor(zptr);
- } 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));
- }
- }
- OBJ_RELEASE(Z_OBJ(obj));
+ zend_assign_op_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -16427,7 +16852,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -16497,7 +16921,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_V
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -16741,7 +17164,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_VAR_CONST_H
#endif
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
zend_free_op free_op1;
@@ -16763,7 +17186,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -16784,51 +17206,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
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)) {
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
+ }
+ } else {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
+ }
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval rv;
-
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval *z, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- incdec_op(z);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(z);
- } else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- }
+ zend_pre_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -16839,15 +17237,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_VAR_CONST(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_VAR_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_VAR_CONST(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_VAR_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
zend_free_op free_op1;
@@ -16869,7 +17267,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -16888,44 +17285,25 @@ 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)) {
- ZVAL_DEREF(zptr);
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
- zval_opt_copy_ctor(zptr);
- incdec_op(zptr);
- } else {
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval rv, obj;
- zval *z;
- zval z_copy;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
}
- ZVAL_DUP(EX_VAR(opline->result.var), z);
- ZVAL_DUP(&z_copy, z);
- incdec_op(&z_copy);
- if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
- Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(&z_copy);
- zval_ptr_dtor(z);
} else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- ZVAL_NULL(EX_VAR(opline->result.var));
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ zval_opt_copy_ctor(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
}
+ } else {
+ zend_post_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var));
}
} while (0);
@@ -16936,12 +17314,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_VAR_CONST(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_VAR_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_VAR_CONST(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_VAR_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -16955,7 +17333,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST);
@@ -16979,7 +17356,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HA
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST);
@@ -17011,7 +17387,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST);
@@ -17048,7 +17423,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST);
@@ -17080,7 +17454,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HAN
offset = EX_CONSTANT(opline->op2);
- if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_VAR == IS_CONST ||
+ (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -17152,7 +17527,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -17185,7 +17559,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HA
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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);
@@ -17226,7 +17599,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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);
@@ -17262,7 +17634,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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);
@@ -17296,7 +17667,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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));
@@ -17325,11 +17695,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HAND
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
-try_assign_dim:
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
try_assign_dim_array:
if (IS_CONST == IS_UNUSED) {
@@ -17357,53 +17725,58 @@ try_assign_dim_array:
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
}
- } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+ } 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);
+ 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, (opline+1)->op1_type, (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_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
- FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
- HANDLE_EXCEPTION();
- } else {
- zend_long offset;
+ } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+ if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ if (IS_CONST == IS_UNUSED) {
+ zend_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
+ FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
+ if (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);
+ dim = EX_CONSTANT(opline->op2);
+ offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W);
- value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ }
+ } 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)) {
+ if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) {
+ goto assign_dim_clean;
+ }
+ goto assign_dim_convert_to_array;
} 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_ISREF_P(object_ptr))) {
- object_ptr = Z_REFVAL_P(object_ptr);
- goto try_assign_dim;
- } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
- if (UNEXPECTED(object_ptr == &EG(error_zval))) {
- goto assign_dim_clean;
- }
- goto assign_dim_convert_to_array;
- } else {
- zend_error(E_WARNING, "Cannot use a scalar value as an array");
+ zend_error(E_WARNING, "Cannot use a scalar value as an array");
assign_dim_clean:
- dim = EX_CONSTANT(opline->op2);
+ dim = EX_CONSTANT(opline->op2);
- value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- FREE_OP(free_op_data1);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ FREE_OP(free_op_data1);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
}
}
if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
@@ -17486,6 +17859,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
function_name = EX_CONSTANT(opline->op2);
if (IS_CONST != IS_CONST) {
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ 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();
}
@@ -17579,7 +17955,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_
SAVE_OPLINE();
if (IS_VAR == IS_UNUSED) {
zend_constant *c;
- zval *retval;
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
@@ -17605,67 +17980,80 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_
} else {
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c);
}
- retval = EX_VAR(opline->result.var);
- ZVAL_COPY_VALUE(retval, &c->value);
- if (Z_OPT_COPYABLE_P(retval) || Z_OPT_REFCOUNTED_P(retval)) {
- if (Z_OPT_COPYABLE_P(retval)) {
- zval_copy_ctor_func(retval);
- } else {
- Z_ADDREF_P(retval);
- }
+#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;
- if (IS_VAR == IS_CONST) {
- if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
- value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
- ZVAL_DEREF(value);
- ZVAL_DUP(EX_VAR(opline->result.var), value);
- goto constant_fetch_end;
- } else if (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(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ do {
+ if (IS_VAR == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
+ value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
+ ZVAL_DEREF(value);
+#ifdef ZTS
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
+#endif
+ break;
+ } else if (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(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
+ if (UNEXPECTED(ce == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1)));
+ HANDLE_EXCEPTION();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
}
- if (UNEXPECTED(ce == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1)));
- 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;
}
- CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
}
- } 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);
- ZVAL_DUP(EX_VAR(opline->result.var), value);
- goto constant_fetch_end;
- }
- }
- 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 (IS_VAR == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value);
+ 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);
+ }
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value);
+ zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
+ HANDLE_EXCEPTION();
}
+ } while (0);
+#ifdef ZTS
+ if (ce->type == ZEND_INTERNAL_CLASS) {
ZVAL_DUP(EX_VAR(opline->result.var), value);
} else {
- zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
+ ZVAL_COPY(EX_VAR(opline->result.var), value);
}
+#else
+ ZVAL_COPY(EX_VAR(opline->result.var), value);
+#endif
}
-constant_fetch_end:
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -17677,11 +18065,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CON
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ 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_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -17691,11 +18078,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CON
} else {
expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
if (IS_VAR == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_VAR == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_VAR == IS_CV) {
@@ -17726,43 +18113,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CON
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if (IS_CONST != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if (IS_CONST != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
} else {
@@ -17810,6 +18195,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDL
zval *container;
zval *offset;
zend_ulong hval;
+ zend_string *key;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
@@ -17821,72 +18207,80 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
offset = EX_CONSTANT(opline->op2);
-unset_dim_again:
- if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht;
+ do {
+ if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ HashTable *ht;
+unset_dim_array:
+ SEPARATE_ARRAY(container);
+ ht = Z_ARRVAL_P(container);
offset_again:
- SEPARATE_ARRAY(container);
- ht = Z_ARRVAL_P(container);
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- zend_hash_index_del(ht, hval);
- break;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index_dim:
- zend_hash_index_del(ht, hval);
- break;
- case IS_STRING:
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ key = Z_STR_P(offset);
if (IS_CONST != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
goto num_index_dim;
}
}
+str_index_dim:
if (ht == &EG(symbol_table)) {
- zend_delete_global_variable(Z_STR_P(offset));
+ zend_delete_global_variable(key);
} else {
- zend_hash_del(ht, Z_STR_P(offset));
+ zend_hash_del(ht, key);
}
- break;
- case IS_NULL:
- zend_hash_del(ht, STR_EMPTY_ALLOC());
- break;
- case IS_FALSE:
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index_dim:
+ zend_hash_index_del(ht, hval);
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto offset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_dim;
- case IS_TRUE:
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_dim;
- case IS_RESOURCE:
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
hval = Z_RES_HANDLE_P(offset);
goto num_index_dim;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto offset_again;
- break;
- default:
+ } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else {
zend_error(E_WARNING, "Illegal offset type in unset");
- break;
+ }
+ break;
+ } else if (IS_VAR != IS_UNUSED && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto unset_dim_array;
+ }
}
- } else if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
- if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
- } else {
- Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
}
- } else if (IS_VAR != IS_UNUSED && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto unset_dim_again;
- } else if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- }
+ if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
+ } else {
+ Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ }
+ } else if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
+ }
+ } while (0);
if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
CHECK_EXCEPTION();
@@ -17910,7 +18304,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
offset = EX_CONSTANT(opline->op2);
@@ -17945,7 +18338,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -17962,7 +18355,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -17972,11 +18365,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z
value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_VAR != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_VAR != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
@@ -17984,7 +18376,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z
if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
- zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -18007,11 +18398,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z
/* Consts, temporary variables and references need copying */
if (IS_VAR == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
zval_ptr_dtor_nogc(free_op1);
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -18032,11 +18426,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z
/* Consts, temporary variables and references need copying */
if (IS_CONST == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -18085,12 +18482,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HAND
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_VAR|IS_TMP_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -18105,12 +18503,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_VAR|IS_TMP_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -18157,7 +18556,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEN
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -18174,7 +18573,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEN
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -18184,11 +18583,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEN
value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_VAR != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_VAR != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
@@ -18196,7 +18594,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEN
if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
- zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -18219,11 +18616,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEN
/* Consts, temporary variables and references need copying */
if (IS_VAR == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
zval_ptr_dtor_nogc(free_op1);
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -18244,11 +18644,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEN
/* Consts, temporary variables and references need copying */
if (IS_TMP_VAR == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -18292,12 +18695,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HAND
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -18312,12 +18716,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -18369,7 +18774,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLE
if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- if (free_op2) {zval_ptr_dtor_nogc(free_op2);};
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
HANDLE_EXCEPTION();
}
@@ -18392,7 +18796,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLE
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
if (free_op2) {zval_ptr_dtor_nogc(free_op2);};
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
if (IS_VAR == IS_VAR &&
@@ -18428,7 +18831,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEN
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -18445,7 +18848,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEN
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -18455,11 +18858,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEN
value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_VAR != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_VAR != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
@@ -18467,7 +18869,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEN
if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
- zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -18490,11 +18891,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEN
/* Consts, temporary variables and references need copying */
if (IS_VAR == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
zval_ptr_dtor_nogc(free_op1);
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -18515,11 +18919,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEN
/* Consts, temporary variables and references need copying */
if (IS_VAR == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
zval_ptr_dtor_nogc(free_op2);
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -18578,7 +18985,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -18865,7 +19271,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HA
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED);
@@ -18889,7 +19294,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED);
@@ -18921,7 +19325,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED);
@@ -18963,11 +19366,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HAN
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
-try_assign_dim:
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
try_assign_dim_array:
if (IS_UNUSED == IS_UNUSED) {
@@ -18995,53 +19396,58 @@ try_assign_dim_array:
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
}
- } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+ } 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;
+ 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, (opline+1)->op1_type, (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_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
- FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
- HANDLE_EXCEPTION();
- } else {
- zend_long offset;
+ } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+ if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ if (IS_UNUSED == IS_UNUSED) {
+ zend_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
+ FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
+ if (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);
+ dim = NULL;
+ offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W);
- value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ }
+ } 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)) {
+ if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) {
+ goto assign_dim_clean;
}
+ goto assign_dim_convert_to_array;
} 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_ISREF_P(object_ptr))) {
- object_ptr = Z_REFVAL_P(object_ptr);
- goto try_assign_dim;
- } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
- if (UNEXPECTED(object_ptr == &EG(error_zval))) {
- goto assign_dim_clean;
- }
- goto assign_dim_convert_to_array;
- } else {
- zend_error(E_WARNING, "Cannot use a scalar value as an array");
+ zend_error(E_WARNING, "Cannot use a scalar value as an array");
assign_dim_clean:
- dim = NULL;
+ dim = NULL;
- value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- FREE_OP(free_op_data1);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ FREE_OP(free_op_data1);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
}
}
if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
@@ -19095,6 +19501,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
function_name = NULL;
if (IS_UNUSED != IS_CONST) {
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ 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();
}
@@ -19224,6 +19633,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN
}
}
zend_verify_return_type(EX(func), retval_ptr);
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zval_ptr_dtor_nogc(free_op1);
+ }
#endif
}
CHECK_EXCEPTION();
@@ -19238,11 +19651,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNU
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ 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_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -19252,11 +19664,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNU
} else {
expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
if (IS_VAR == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_VAR == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_VAR == IS_CV) {
@@ -19287,43 +19699,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNU
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if (IS_UNUSED != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if (IS_UNUSED != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
} else {
@@ -19388,7 +19798,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -19405,7 +19815,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -19415,11 +19825,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(
value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_VAR != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_VAR != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
@@ -19427,7 +19836,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(
if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
- zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -19450,11 +19858,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(
/* Consts, temporary variables and references need copying */
if (IS_VAR == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
zval_ptr_dtor_nogc(free_op1);
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -19475,11 +19886,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(
/* Consts, temporary variables and references need copying */
if (IS_UNUSED == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -19523,12 +19937,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDL
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_SMART_BRANCH(result, (IS_VAR|IS_CV) & (IS_VAR|IS_TMP_VAR));
@@ -19543,12 +19958,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_H
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_SMART_BRANCH(result, (IS_VAR|IS_CV) & (IS_VAR|IS_TMP_VAR));
@@ -19584,7 +20000,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -19614,42 +20029,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval *z;
- zval rv, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- if (Z_OBJ_HT(obj)->read_property &&
- (z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
- if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- zptr = z;
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- binary_op(z, z, value);
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- zval_ptr_dtor(zptr);
- } 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));
- }
- }
- OBJ_RELEASE(Z_OBJ(obj));
+ zend_assign_op_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -19681,7 +20061,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -19751,7 +20130,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_V
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -19995,7 +20373,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_VAR_CV_HAND
#endif
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
zend_free_op free_op1;
@@ -20017,7 +20395,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -20038,51 +20415,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
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)) {
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
+ }
+ } else {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
+ }
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval rv;
-
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval *z, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- incdec_op(z);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(z);
- } else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- }
+ zend_pre_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -20093,15 +20446,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_VAR_CV(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_VAR_CV(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_VAR_CV(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_VAR_CV(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
zend_free_op free_op1;
@@ -20123,7 +20476,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -20142,44 +20494,25 @@ 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)) {
- ZVAL_DEREF(zptr);
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
- zval_opt_copy_ctor(zptr);
- incdec_op(zptr);
- } else {
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval rv, obj;
- zval *z;
- zval z_copy;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
}
- ZVAL_DUP(EX_VAR(opline->result.var), z);
- ZVAL_DUP(&z_copy, z);
- incdec_op(&z_copy);
- if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
- Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(&z_copy);
- zval_ptr_dtor(z);
} else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- ZVAL_NULL(EX_VAR(opline->result.var));
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ zval_opt_copy_ctor(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
}
+ } else {
+ zend_post_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var));
}
} while (0);
@@ -20190,12 +20523,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_VAR_CV(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_VAR_CV(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_VAR_CV(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_VAR_CV(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -20209,7 +20542,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLE
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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);
@@ -20233,7 +20565,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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);
@@ -20265,7 +20596,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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);
@@ -20302,7 +20632,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HA
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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);
@@ -20334,7 +20663,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLE
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_VAR == IS_CONST ||
+ (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -20406,7 +20736,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLE
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -20439,7 +20768,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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);
@@ -20480,7 +20808,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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);
@@ -20516,7 +20843,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HA
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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);
@@ -20550,7 +20876,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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));
@@ -20579,11 +20904,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
-try_assign_dim:
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
try_assign_dim_array:
if (IS_CV == IS_UNUSED) {
@@ -20611,53 +20934,58 @@ try_assign_dim_array:
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
}
- } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+ } 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);
+ 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, (opline+1)->op1_type, (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_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
- FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
- HANDLE_EXCEPTION();
- } else {
- zend_long offset;
+ } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+ if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ if (IS_CV == IS_UNUSED) {
+ zend_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
+ FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
+ if (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);
+ 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_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ }
+ } 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)) {
+ if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) {
+ goto assign_dim_clean;
}
+ goto assign_dim_convert_to_array;
} 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_ISREF_P(object_ptr))) {
- object_ptr = Z_REFVAL_P(object_ptr);
- goto try_assign_dim;
- } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
- if (UNEXPECTED(object_ptr == &EG(error_zval))) {
- goto assign_dim_clean;
- }
- goto assign_dim_convert_to_array;
- } else {
- zend_error(E_WARNING, "Cannot use a scalar value as an array");
+ zend_error(E_WARNING, "Cannot use a scalar value as an array");
assign_dim_clean:
- dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- FREE_OP(free_op_data1);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ FREE_OP(free_op_data1);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
}
}
if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
@@ -20708,7 +21036,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER
if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
-
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
HANDLE_EXCEPTION();
}
@@ -20731,7 +21058,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
if (IS_VAR == IS_VAR &&
@@ -20800,9 +21126,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
} else if (IS_CV != IS_UNUSED) {
- function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ 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)) {
+ 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();
}
@@ -20897,11 +21226,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ 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_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -20911,11 +21239,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_
} else {
expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
if (IS_VAR == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_VAR == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_VAR == IS_CV) {
@@ -20941,48 +21269,46 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_
if (IS_CV != IS_UNUSED) {
- zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ zval *offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
zend_string *str;
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if (IS_CV != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if (IS_CV != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
} else {
@@ -21030,6 +21356,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(
zval *container;
zval *offset;
zend_ulong hval;
+ zend_string *key;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
@@ -21041,72 +21368,80 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
- offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
-unset_dim_again:
- if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht;
+ do {
+ if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ HashTable *ht;
+unset_dim_array:
+ SEPARATE_ARRAY(container);
+ ht = Z_ARRVAL_P(container);
offset_again:
- SEPARATE_ARRAY(container);
- ht = Z_ARRVAL_P(container);
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- zend_hash_index_del(ht, hval);
- break;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index_dim:
- zend_hash_index_del(ht, hval);
- break;
- case IS_STRING:
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ key = Z_STR_P(offset);
if (IS_CV != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
goto num_index_dim;
}
}
+str_index_dim:
if (ht == &EG(symbol_table)) {
- zend_delete_global_variable(Z_STR_P(offset));
+ zend_delete_global_variable(key);
} else {
- zend_hash_del(ht, Z_STR_P(offset));
+ zend_hash_del(ht, key);
}
- break;
- case IS_NULL:
- zend_hash_del(ht, STR_EMPTY_ALLOC());
- break;
- case IS_FALSE:
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index_dim:
+ zend_hash_index_del(ht, hval);
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto offset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_dim;
- case IS_TRUE:
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_dim;
- case IS_RESOURCE:
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
hval = Z_RES_HANDLE_P(offset);
goto num_index_dim;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto offset_again;
- break;
- default:
+ } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else {
zend_error(E_WARNING, "Illegal offset type in unset");
- break;
+ }
+ break;
+ } else if (IS_VAR != IS_UNUSED && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto unset_dim_array;
+ }
}
- } else if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
- if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
- } else {
- Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
}
- } else if (IS_VAR != IS_UNUSED && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto unset_dim_again;
- } else if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- }
+ if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
+ } else {
+ Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ }
+ } else if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
+ }
+ } while (0);
if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
CHECK_EXCEPTION();
@@ -21130,7 +21465,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
@@ -21165,7 +21499,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -21182,7 +21516,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -21192,11 +21526,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND
value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_VAR != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_VAR != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
@@ -21204,7 +21537,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND
if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
- zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -21227,11 +21559,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND
/* Consts, temporary variables and references need copying */
if (IS_VAR == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
zval_ptr_dtor_nogc(free_op1);
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -21252,11 +21587,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND
/* Consts, temporary variables and references need copying */
if (IS_CV == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -21326,7 +21664,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
zval_ptr_dtor_nogc(free_op2);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -21356,42 +21693,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval *z;
- zval rv, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- if (Z_OBJ_HT(obj)->read_property &&
- (z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
- if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- zptr = z;
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- binary_op(z, z, value);
- Z_OBJ_HT(obj)->write_property(&obj, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- zval_ptr_dtor(zptr);
- } 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));
- }
- }
- OBJ_RELEASE(Z_OBJ(obj));
+ zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -21423,7 +21725,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "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));
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -21494,7 +21795,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_V
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
zval_ptr_dtor_nogc(free_op2);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -21739,7 +22039,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_
#endif
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -21761,7 +22061,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
zval_ptr_dtor_nogc(free_op2);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -21782,51 +22081,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
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)) {
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
+ }
+ } else {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
+ }
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval rv;
-
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval *z, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- incdec_op(z);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- Z_OBJ_HT(obj)->write_property(&obj, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(z);
- } else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- }
+ zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -21838,15 +22113,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -21868,7 +22143,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
zval_ptr_dtor_nogc(free_op2);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -21887,44 +22161,25 @@ 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)) {
- ZVAL_DEREF(zptr);
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
- zval_opt_copy_ctor(zptr);
- incdec_op(zptr);
- } else {
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval rv, obj;
- zval *z;
- zval z_copy;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
}
- ZVAL_DUP(EX_VAR(opline->result.var), z);
- ZVAL_DUP(&z_copy, z);
- incdec_op(&z_copy);
- if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
- Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(&z_copy);
- zval_ptr_dtor(z);
} else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- ZVAL_NULL(EX_VAR(opline->result.var));
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ zval_opt_copy_ctor(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
}
+ } else {
+ zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var));
}
} while (0);
@@ -21936,12 +22191,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -21955,7 +22210,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HA
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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));
@@ -21979,7 +22233,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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));
@@ -22011,7 +22264,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TM
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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));
@@ -22048,7 +22300,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVA
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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));
@@ -22080,7 +22331,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_HA
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_VAR == IS_CONST ||
+ (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -22153,7 +22405,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HA
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
zval_ptr_dtor_nogc(free_op2);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
@@ -22186,7 +22437,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
zval_ptr_dtor_nogc(free_op2);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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);
@@ -22227,7 +22477,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TM
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
zval_ptr_dtor_nogc(free_op2);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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);
@@ -22263,7 +22512,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVA
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
zval_ptr_dtor_nogc(free_op2);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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);
@@ -22297,7 +22545,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
zval_ptr_dtor_nogc(free_op2);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
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));
@@ -22326,11 +22573,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_HAN
zend_error(E_EXCEPTION | E_ERROR, "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));
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
-try_assign_dim:
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
try_assign_dim_array:
if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
@@ -22358,53 +22603,58 @@ try_assign_dim_array:
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
}
- } else 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);
+ } 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, (opline+1)->op1_type, (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_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
- FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
- HANDLE_EXCEPTION();
- } else {
- zend_long offset;
+ 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);
+ 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_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
+ FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
+ if (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_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ 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_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ }
+ } 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)) {
+ if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) {
+ goto assign_dim_clean;
+ }
+ goto assign_dim_convert_to_array;
} 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_ISREF_P(object_ptr))) {
- object_ptr = Z_REFVAL_P(object_ptr);
- goto try_assign_dim;
- } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
- if (UNEXPECTED(object_ptr == &EG(error_zval))) {
- goto assign_dim_clean;
- }
- goto assign_dim_convert_to_array;
- } else {
- zend_error(E_WARNING, "Cannot use a scalar value as an array");
+ zend_error(E_WARNING, "Cannot use a scalar value as an array");
assign_dim_clean:
- dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- zval_ptr_dtor_nogc(free_op2);
- value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- FREE_OP(free_op_data1);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ zval_ptr_dtor_nogc(free_op2);
+ value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ FREE_OP(free_op_data1);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
}
}
if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
@@ -22458,6 +22708,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
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)) {
+ 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();
}
@@ -22552,11 +22805,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ 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_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -22566,11 +22818,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP
} else {
expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
if (IS_VAR == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_VAR == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_VAR == IS_CV) {
@@ -22601,43 +22853,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
zval_ptr_dtor_nogc(free_op2);
} else {
@@ -22685,6 +22935,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HAND
zval *container;
zval *offset;
zend_ulong hval;
+ zend_string *key;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
@@ -22696,72 +22947,81 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
-unset_dim_again:
- if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht;
+ do {
+ if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ HashTable *ht;
+unset_dim_array:
+ SEPARATE_ARRAY(container);
+ ht = Z_ARRVAL_P(container);
offset_again:
- SEPARATE_ARRAY(container);
- ht = Z_ARRVAL_P(container);
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- zend_hash_index_del(ht, hval);
- break;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index_dim:
- zend_hash_index_del(ht, hval);
- break;
- case IS_STRING:
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ key = Z_STR_P(offset);
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
goto num_index_dim;
}
}
+str_index_dim:
if (ht == &EG(symbol_table)) {
- zend_delete_global_variable(Z_STR_P(offset));
+ zend_delete_global_variable(key);
} else {
- zend_hash_del(ht, Z_STR_P(offset));
+ zend_hash_del(ht, key);
}
- break;
- case IS_NULL:
- zend_hash_del(ht, STR_EMPTY_ALLOC());
- break;
- case IS_FALSE:
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index_dim:
+ zend_hash_index_del(ht, hval);
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto offset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_dim;
- case IS_TRUE:
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_dim;
- case IS_RESOURCE:
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
hval = Z_RES_HANDLE_P(offset);
goto num_index_dim;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto offset_again;
- break;
- default:
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else {
zend_error(E_WARNING, "Illegal offset type in unset");
- break;
+ }
+ break;
+ } else if (IS_VAR != IS_UNUSED && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto unset_dim_array;
+ }
}
- } else if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
- if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
- } else {
- Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
}
- } else if (IS_VAR != IS_UNUSED && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto unset_dim_again;
- } else if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- }
+ if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
+ } else {
+ Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ }
+ } else if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
+ }
+ } while (0);
+
zval_ptr_dtor_nogc(free_op2);
if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
CHECK_EXCEPTION();
@@ -22785,7 +23045,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
@@ -22844,7 +23103,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND
if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) {
break;
}
- }
+ }
+ if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(obj, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -22954,7 +23216,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
-
HANDLE_EXCEPTION();
}
@@ -22984,42 +23245,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval *z;
- zval rv, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- if (Z_OBJ_HT(obj)->read_property &&
- (z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
- if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- zptr = z;
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- binary_op(z, z, value);
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- zval_ptr_dtor(zptr);
- } 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));
- }
- }
- OBJ_RELEASE(Z_OBJ(obj));
+ zend_assign_op_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -23051,7 +23277,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
-
HANDLE_EXCEPTION();
}
@@ -23327,7 +23552,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_CONS
#endif
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
@@ -23349,7 +23574,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -23370,51 +23594,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
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)) {
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
+ }
+ } else {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
+ }
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval rv;
-
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval *z, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- incdec_op(z);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(z);
- } else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- }
+ zend_pre_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -23425,15 +23625,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
@@ -23455,7 +23655,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -23474,44 +23673,25 @@ 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)) {
- ZVAL_DEREF(zptr);
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
- zval_opt_copy_ctor(zptr);
- incdec_op(zptr);
- } else {
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval rv, obj;
- zval *z;
- zval z_copy;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
}
- ZVAL_DUP(EX_VAR(opline->result.var), z);
- ZVAL_DUP(&z_copy, z);
- incdec_op(&z_copy);
- if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
- Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(&z_copy);
- zval_ptr_dtor(z);
} else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- ZVAL_NULL(EX_VAR(opline->result.var));
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ zval_opt_copy_ctor(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
}
+ } else {
+ zend_post_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var));
}
} while (0);
@@ -23522,12 +23702,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_UNUSED_CONST(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_UNUSED_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_UNUSED_CONST(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_UNUSED_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -23549,7 +23729,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_
offset = EX_CONSTANT(opline->op2);
- if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_UNUSED == IS_CONST ||
+ (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -23621,7 +23802,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
-
HANDLE_EXCEPTION();
}
@@ -23654,7 +23834,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -23686,7 +23865,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST
offset = EX_CONSTANT(opline->op2);
- if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_UNUSED == IS_CONST ||
+ (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -23767,7 +23947,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -23803,7 +23982,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CO
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -23837,7 +24015,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_H
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
-
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));
@@ -23862,11 +24039,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HA
var = EX_CONSTANT(opline->op2);
rope[0] = zend_string_copy(Z_STR_P(var));
} else {
- SAVE_OPLINE();
var = EX_CONSTANT(opline->op2);
- rope[0] = zval_get_string(var);
+ if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+ if (IS_CONST == IS_CV) {
+ rope[0] = zend_string_copy(Z_STR_P(var));
+ } else {
+ rope[0] = Z_STR_P(var);
+ }
+ } else {
+ SAVE_OPLINE();
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(var, BP_VAR_R);
+ }
+ rope[0] = _zval_get_string_func(var);
- CHECK_EXCEPTION();
+ CHECK_EXCEPTION();
+ }
}
ZEND_VM_NEXT_OPCODE();
}
@@ -23896,6 +24084,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
break;
}
}
+ 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();
}
@@ -23916,13 +24107,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
if (IS_UNUSED != IS_UNUSED) {
do {
- if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (IS_UNUSED == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
break;
}
}
+ if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(object, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -23969,7 +24163,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
- } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR)) {
+ } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+ /* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@@ -23991,7 +24186,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON
SAVE_OPLINE();
if (IS_UNUSED == IS_UNUSED) {
zend_constant *c;
- zval *retval;
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
@@ -24017,67 +24211,80 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON
} else {
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c);
}
- retval = EX_VAR(opline->result.var);
- ZVAL_COPY_VALUE(retval, &c->value);
- if (Z_OPT_COPYABLE_P(retval) || Z_OPT_REFCOUNTED_P(retval)) {
- if (Z_OPT_COPYABLE_P(retval)) {
- zval_copy_ctor_func(retval);
- } else {
- Z_ADDREF_P(retval);
- }
+#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;
- if (IS_UNUSED == IS_CONST) {
- if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
- value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
- ZVAL_DEREF(value);
- ZVAL_DUP(EX_VAR(opline->result.var), value);
- goto constant_fetch_end;
- } else if (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(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ do {
+ if (IS_UNUSED == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
+ value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
+ ZVAL_DEREF(value);
+#ifdef ZTS
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
+#endif
+ break;
+ } else if (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(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
+ if (UNEXPECTED(ce == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1)));
+ HANDLE_EXCEPTION();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
}
- if (UNEXPECTED(ce == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1)));
- 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;
}
- CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
}
- } 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);
- ZVAL_DUP(EX_VAR(opline->result.var), value);
- goto constant_fetch_end;
- }
- }
- 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 (IS_UNUSED == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value);
+ 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);
+ }
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value);
+ zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
+ HANDLE_EXCEPTION();
}
+ } while (0);
+#ifdef ZTS
+ if (ce->type == ZEND_INTERNAL_CLASS) {
ZVAL_DUP(EX_VAR(opline->result.var), value);
} else {
- zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
+ ZVAL_COPY(EX_VAR(opline->result.var), value);
}
+#else
+ ZVAL_COPY(EX_VAR(opline->result.var), value);
+#endif
}
-constant_fetch_end:
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -24119,6 +24326,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HA
zval *container;
zval *offset;
zend_ulong hval;
+ zend_string *key;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data);
@@ -24130,72 +24338,80 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HA
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
-
HANDLE_EXCEPTION();
}
offset = EX_CONSTANT(opline->op2);
-unset_dim_again:
- if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht;
+ do {
+ if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ HashTable *ht;
+unset_dim_array:
+ SEPARATE_ARRAY(container);
+ ht = Z_ARRVAL_P(container);
offset_again:
- SEPARATE_ARRAY(container);
- ht = Z_ARRVAL_P(container);
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- zend_hash_index_del(ht, hval);
- break;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index_dim:
- zend_hash_index_del(ht, hval);
- break;
- case IS_STRING:
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ key = Z_STR_P(offset);
if (IS_CONST != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
goto num_index_dim;
}
}
+str_index_dim:
if (ht == &EG(symbol_table)) {
- zend_delete_global_variable(Z_STR_P(offset));
+ zend_delete_global_variable(key);
} else {
- zend_hash_del(ht, Z_STR_P(offset));
+ zend_hash_del(ht, key);
}
- break;
- case IS_NULL:
- zend_hash_del(ht, STR_EMPTY_ALLOC());
- break;
- case IS_FALSE:
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index_dim:
+ zend_hash_index_del(ht, hval);
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto offset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_dim;
- case IS_TRUE:
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_dim;
- case IS_RESOURCE:
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
hval = Z_RES_HANDLE_P(offset);
goto num_index_dim;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto offset_again;
- break;
- default:
+ } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else {
zend_error(E_WARNING, "Illegal offset type in unset");
- break;
+ }
+ break;
+ } else if (IS_UNUSED != IS_UNUSED && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto unset_dim_array;
+ }
}
- } else if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
- if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
- } else {
- Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
}
- } else if (IS_UNUSED != IS_UNUSED && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto unset_dim_again;
- } else if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- }
+ if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
+ } else {
+ Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ }
+ } else if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
+ }
+ } while (0);
CHECK_EXCEPTION();
@@ -24219,7 +24435,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HA
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
-
HANDLE_EXCEPTION();
}
offset = EX_CONSTANT(opline->op2);
@@ -24267,12 +24482,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNU
offset = EX_CONSTANT(opline->op2);
-isset_dim_obj_again:
if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
zval *value;
zend_string *str;
+isset_dim_obj_array:
+ ht = Z_ARRVAL_P(container);
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
@@ -24287,31 +24503,31 @@ str_index_prop:
hval = Z_LVAL_P(offset);
num_index_prop:
value = zend_hash_index_find(ht, hval);
- } else {
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index_prop;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index_prop;
- case IS_FALSE:
- hval = 0;
- goto num_index_prop;
- case IS_TRUE:
- hval = 1;
- goto num_index_prop;
- case IS_RESOURCE:
- hval = Z_RES_HANDLE_P(offset);
- goto num_index_prop;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto isset_again;
- default:
- zend_error(E_WARNING, "Illegal offset type in isset or empty");
- value = NULL;
- break;
- }
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+ offset = Z_REFVAL_P(offset);
+ goto isset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ hval = Z_RES_HANDLE_P(offset);
+ goto num_index_prop;
+ } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type in isset or empty");
+ goto isset_not_found;
}
if (opline->extended_value & ZEND_ISSET) {
@@ -24321,50 +24537,62 @@ num_index_prop:
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value));
}
- } else if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ goto isset_dim_obj_exit;
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto isset_dim_obj_array;
+ }
+ }
+
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ }
+
+ if (IS_UNUSED == IS_UNUSED ||
+ (IS_UNUSED != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
- result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
- result = 0;
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
+ goto isset_not_found;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
- zval tmp;
+ zend_long lval;
- result = 0;
- if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ lval = Z_LVAL_P(offset);
+isset_str_offset:
+ if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
+ if (opline->extended_value & ZEND_ISSET) {
+ result = 1;
+ } else {
+ result = (Z_STRVAL_P(container)[lval] == '0');
+ }
+ } else {
+ goto isset_not_found;
+ }
+ } else {
if (IS_CONST & (IS_CV|IS_VAR)) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
- ZVAL_DUP(&tmp, offset);
- convert_to_long(&tmp);
- offset = &tmp;
- }
- }
- if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
- if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
- if ((opline->extended_value & ZEND_ISSET) ||
- Z_STRVAL_P(container)[offset->value.lval] != '0') {
- result = 1;
- }
+ lval = zval_get_long(offset);
+ goto isset_str_offset;
}
+ goto isset_not_found;
}
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
- } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto isset_dim_obj_again;
} else {
+isset_not_found:
result = ((opline->extended_value & ZEND_ISSET) == 0);
}
+isset_dim_obj_exit:
+
ZEND_VM_SMART_BRANCH(result, 1);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
@@ -24391,7 +24619,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN
offset = EX_CONSTANT(opline->op2);
- if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_UNUSED == IS_CONST ||
+ (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -24406,10 +24635,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN
isset_no_object:
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
- result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
}
@@ -24426,7 +24654,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
@@ -24443,7 +24671,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE
if (IS_UNUSED != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -24453,11 +24681,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE
value = NULL;
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_UNUSED != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_UNUSED != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -24465,7 +24692,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE
if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
-
HANDLE_EXCEPTION();
}
@@ -24487,11 +24713,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE
/* Consts, temporary variables and references need copying */
if (IS_UNUSED == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -24512,11 +24741,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE
/* Consts, temporary variables and references need copying */
if (IS_CONST == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -24563,7 +24795,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
@@ -24580,7 +24812,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(
if (IS_UNUSED != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -24590,11 +24822,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(
value = NULL;
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_UNUSED != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_UNUSED != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -24602,7 +24833,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(
if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-
HANDLE_EXCEPTION();
}
@@ -24624,11 +24854,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(
/* Consts, temporary variables and references need copying */
if (IS_UNUSED == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -24649,11 +24882,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(
/* Consts, temporary variables and references need copying */
if (IS_TMP_VAR == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -24700,7 +24936,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
@@ -24717,7 +24953,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(
if (IS_UNUSED != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -24727,11 +24963,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(
value = NULL;
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_UNUSED != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_UNUSED != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -24739,7 +24974,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(
if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-
HANDLE_EXCEPTION();
}
@@ -24761,11 +24995,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(
/* Consts, temporary variables and references need copying */
if (IS_UNUSED == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -24786,11 +25023,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(
/* Consts, temporary variables and references need copying */
if (IS_VAR == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
zval_ptr_dtor_nogc(free_op2);
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -24849,7 +25089,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
-
HANDLE_EXCEPTION();
}
@@ -25168,6 +25407,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED
}
}
zend_verify_return_type(EX(func), retval_ptr);
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ }
#endif
}
CHECK_EXCEPTION();
@@ -25212,7 +25455,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
@@ -25229,7 +25472,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL
if (IS_UNUSED != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -25239,11 +25482,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL
value = NULL;
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_UNUSED != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_UNUSED != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -25251,7 +25493,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL
if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
-
HANDLE_EXCEPTION();
}
@@ -25273,11 +25514,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL
/* Consts, temporary variables and references need copying */
if (IS_UNUSED == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -25298,11 +25542,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL
/* Consts, temporary variables and references need copying */
if (IS_UNUSED == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -25367,7 +25614,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
-
HANDLE_EXCEPTION();
}
@@ -25397,42 +25643,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval *z;
- zval rv, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- if (Z_OBJ_HT(obj)->read_property &&
- (z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
- if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- zptr = z;
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- binary_op(z, z, value);
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- zval_ptr_dtor(zptr);
- } 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));
- }
- }
- OBJ_RELEASE(Z_OBJ(obj));
+ zend_assign_op_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -25464,7 +25675,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
-
HANDLE_EXCEPTION();
}
@@ -25740,7 +25950,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_CV_H
#endif
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
@@ -25762,7 +25972,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -25783,51 +25992,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
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)) {
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
+ }
+ } else {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
+ }
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval rv;
-
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval *z, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- incdec_op(z);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(z);
- } else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- }
+ zend_pre_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -25838,15 +26023,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_UNUSED_CV(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_UNUSED_CV(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_UNUSED_CV(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_UNUSED_CV(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
@@ -25868,7 +26053,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -25887,44 +26071,25 @@ 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)) {
- ZVAL_DEREF(zptr);
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
- zval_opt_copy_ctor(zptr);
- incdec_op(zptr);
- } else {
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval rv, obj;
- zval *z;
- zval z_copy;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
}
- ZVAL_DUP(EX_VAR(opline->result.var), z);
- ZVAL_DUP(&z_copy, z);
- incdec_op(&z_copy);
- if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
- Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(&z_copy);
- zval_ptr_dtor(z);
} else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- ZVAL_NULL(EX_VAR(opline->result.var));
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ zval_opt_copy_ctor(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
}
+ } else {
+ zend_post_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var));
}
} while (0);
@@ -25935,12 +26100,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_UNUSED_CV(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_UNUSED_CV(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_UNUSED_CV(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_UNUSED_CV(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -25962,7 +26127,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_UNUSED == IS_CONST ||
+ (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -26034,7 +26200,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HAN
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
-
HANDLE_EXCEPTION();
}
@@ -26067,7 +26232,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HA
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -26099,7 +26263,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HA
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_UNUSED == IS_CONST ||
+ (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -26180,7 +26345,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -26216,7 +26380,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -26250,7 +26413,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HAND
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
-
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));
@@ -26275,11 +26437,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CV_HANDL
var = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
rope[0] = zend_string_copy(Z_STR_P(var));
} else {
- SAVE_OPLINE();
- var = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- rope[0] = zval_get_string(var);
+ var = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+ if (IS_CV == IS_CV) {
+ rope[0] = zend_string_copy(Z_STR_P(var));
+ } else {
+ rope[0] = Z_STR_P(var);
+ }
+ } else {
+ SAVE_OPLINE();
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(var, BP_VAR_R);
+ }
+ rope[0] = _zval_get_string_func(var);
- CHECK_EXCEPTION();
+ CHECK_EXCEPTION();
+ }
}
ZEND_VM_NEXT_OPCODE();
}
@@ -26298,7 +26471,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
SAVE_OPLINE();
- function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ function_name = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
@@ -26309,6 +26482,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
break;
}
}
+ 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();
}
@@ -26329,13 +26505,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
if (IS_UNUSED != IS_UNUSED) {
do {
- if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (IS_UNUSED == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
break;
}
}
+ if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(object, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -26382,7 +26561,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
- } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR)) {
+ } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+ /* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@@ -26435,6 +26615,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDL
zval *container;
zval *offset;
zend_ulong hval;
+ zend_string *key;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data);
@@ -26446,72 +26627,80 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDL
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
-
HANDLE_EXCEPTION();
}
- offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
-unset_dim_again:
- if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht;
+ do {
+ if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ HashTable *ht;
+unset_dim_array:
+ SEPARATE_ARRAY(container);
+ ht = Z_ARRVAL_P(container);
offset_again:
- SEPARATE_ARRAY(container);
- ht = Z_ARRVAL_P(container);
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- zend_hash_index_del(ht, hval);
- break;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index_dim:
- zend_hash_index_del(ht, hval);
- break;
- case IS_STRING:
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ key = Z_STR_P(offset);
if (IS_CV != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
goto num_index_dim;
}
}
+str_index_dim:
if (ht == &EG(symbol_table)) {
- zend_delete_global_variable(Z_STR_P(offset));
+ zend_delete_global_variable(key);
} else {
- zend_hash_del(ht, Z_STR_P(offset));
+ zend_hash_del(ht, key);
}
- break;
- case IS_NULL:
- zend_hash_del(ht, STR_EMPTY_ALLOC());
- break;
- case IS_FALSE:
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index_dim:
+ zend_hash_index_del(ht, hval);
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto offset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_dim;
- case IS_TRUE:
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_dim;
- case IS_RESOURCE:
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
hval = Z_RES_HANDLE_P(offset);
goto num_index_dim;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto offset_again;
- break;
- default:
+ } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else {
zend_error(E_WARNING, "Illegal offset type in unset");
- break;
+ }
+ break;
+ } else if (IS_UNUSED != IS_UNUSED && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto unset_dim_array;
+ }
}
- } else if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
- if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
- } else {
- Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
}
- } else if (IS_UNUSED != IS_UNUSED && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto unset_dim_again;
- } else if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- }
+ if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
+ } else {
+ Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ }
+ } else if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
+ }
+ } while (0);
CHECK_EXCEPTION();
@@ -26535,7 +26724,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDL
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
-
HANDLE_EXCEPTION();
}
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
@@ -26581,14 +26769,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNU
HANDLE_EXCEPTION();
}
- offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
-isset_dim_obj_again:
if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
zval *value;
zend_string *str;
+isset_dim_obj_array:
+ ht = Z_ARRVAL_P(container);
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
@@ -26603,31 +26792,31 @@ str_index_prop:
hval = Z_LVAL_P(offset);
num_index_prop:
value = zend_hash_index_find(ht, hval);
- } else {
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index_prop;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index_prop;
- case IS_FALSE:
- hval = 0;
- goto num_index_prop;
- case IS_TRUE:
- hval = 1;
- goto num_index_prop;
- case IS_RESOURCE:
- hval = Z_RES_HANDLE_P(offset);
- goto num_index_prop;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto isset_again;
- default:
- zend_error(E_WARNING, "Illegal offset type in isset or empty");
- value = NULL;
- break;
- }
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+ offset = Z_REFVAL_P(offset);
+ goto isset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ hval = Z_RES_HANDLE_P(offset);
+ goto num_index_prop;
+ } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type in isset or empty");
+ goto isset_not_found;
}
if (opline->extended_value & ZEND_ISSET) {
@@ -26637,50 +26826,62 @@ num_index_prop:
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value));
}
- } else if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ goto isset_dim_obj_exit;
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto isset_dim_obj_array;
+ }
+ }
+
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ }
+
+ if (IS_UNUSED == IS_UNUSED ||
+ (IS_UNUSED != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
- result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
- result = 0;
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
+ goto isset_not_found;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
- zval tmp;
+ zend_long lval;
- result = 0;
- if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ lval = Z_LVAL_P(offset);
+isset_str_offset:
+ if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
+ if (opline->extended_value & ZEND_ISSET) {
+ result = 1;
+ } else {
+ result = (Z_STRVAL_P(container)[lval] == '0');
+ }
+ } else {
+ goto isset_not_found;
+ }
+ } else {
if (IS_CV & (IS_CV|IS_VAR)) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
- ZVAL_DUP(&tmp, offset);
- convert_to_long(&tmp);
- offset = &tmp;
+ lval = zval_get_long(offset);
+ goto isset_str_offset;
}
+ goto isset_not_found;
}
- if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
- if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
- if ((opline->extended_value & ZEND_ISSET) ||
- Z_STRVAL_P(container)[offset->value.lval] != '0') {
- result = 1;
- }
- }
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
- } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto isset_dim_obj_again;
} else {
+isset_not_found:
result = ((opline->extended_value & ZEND_ISSET) == 0);
}
+isset_dim_obj_exit:
+
ZEND_VM_SMART_BRANCH(result, 1);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
@@ -26707,7 +26908,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_UNUSED == IS_CONST ||
+ (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -26722,10 +26924,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN
isset_no_object:
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
- result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
}
@@ -26742,7 +26943,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
@@ -26759,7 +26960,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z
if (IS_UNUSED != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -26769,11 +26970,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z
value = NULL;
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_UNUSED != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_UNUSED != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = NULL;
@@ -26781,7 +26981,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z
if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
-
HANDLE_EXCEPTION();
}
@@ -26803,11 +27002,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z
/* Consts, temporary variables and references need copying */
if (IS_UNUSED == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -26828,11 +27030,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z
/* Consts, temporary variables and references need copying */
if (IS_CV == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -26897,7 +27102,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "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();
}
@@ -26927,42 +27131,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval *z;
- zval rv, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- if (Z_OBJ_HT(obj)->read_property &&
- (z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
- if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- zptr = z;
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- binary_op(z, z, value);
- Z_OBJ_HT(obj)->write_property(&obj, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- zval_ptr_dtor(zptr);
- } 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));
- }
- }
- OBJ_RELEASE(Z_OBJ(obj));
+ zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -26994,7 +27163,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "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();
}
@@ -27271,7 +27439,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_TMPV
#endif
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
zend_free_op free_op2;
@@ -27293,7 +27461,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
zval_ptr_dtor_nogc(free_op2);
-
HANDLE_EXCEPTION();
}
@@ -27314,51 +27481,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
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)) {
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
+ }
+ } else {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
+ }
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval rv;
-
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval *z, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- incdec_op(z);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- Z_OBJ_HT(obj)->write_property(&obj, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(z);
- } else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- }
+ zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -27370,15 +27513,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
zend_free_op free_op2;
@@ -27400,7 +27543,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
zval_ptr_dtor_nogc(free_op2);
-
HANDLE_EXCEPTION();
}
@@ -27419,44 +27561,25 @@ 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)) {
- ZVAL_DEREF(zptr);
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
- zval_opt_copy_ctor(zptr);
- incdec_op(zptr);
- } else {
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval rv, obj;
- zval *z;
- zval z_copy;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
}
- ZVAL_DUP(EX_VAR(opline->result.var), z);
- ZVAL_DUP(&z_copy, z);
- incdec_op(&z_copy);
- if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
- Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(&z_copy);
- zval_ptr_dtor(z);
} else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- ZVAL_NULL(EX_VAR(opline->result.var));
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ zval_opt_copy_ctor(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
}
+ } else {
+ zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var));
}
} while (0);
@@ -27468,12 +27591,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -27495,7 +27618,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_UNUSED == IS_CONST ||
+ (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -27568,7 +27692,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
zval_ptr_dtor_nogc(free_op2);
-
HANDLE_EXCEPTION();
}
@@ -27601,7 +27724,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVA
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -27633,7 +27755,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVA
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_UNUSED == IS_CONST ||
+ (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -27715,7 +27838,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -27751,7 +27873,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TM
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -27785,7 +27906,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
zval_ptr_dtor_nogc(free_op2);
-
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));
@@ -27810,11 +27930,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_H
var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
rope[0] = zend_string_copy(Z_STR_P(var));
} else {
- SAVE_OPLINE();
var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- rope[0] = zval_get_string(var);
- zval_ptr_dtor_nogc(free_op2);
- CHECK_EXCEPTION();
+ if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
+ rope[0] = zend_string_copy(Z_STR_P(var));
+ } else {
+ rope[0] = Z_STR_P(var);
+ }
+ } else {
+ SAVE_OPLINE();
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(var, BP_VAR_R);
+ }
+ rope[0] = _zval_get_string_func(var);
+ zval_ptr_dtor_nogc(free_op2);
+ CHECK_EXCEPTION();
+ }
}
ZEND_VM_NEXT_OPCODE();
}
@@ -27844,6 +27975,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
break;
}
}
+ 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();
}
@@ -27864,13 +27998,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
if (IS_UNUSED != IS_UNUSED) {
do {
- if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (IS_UNUSED == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
break;
}
}
+ if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(object, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -27917,7 +28054,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
- } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR)) {
+ } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+ /* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@@ -27971,6 +28109,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMPVAR_H
zval *container;
zval *offset;
zend_ulong hval;
+ zend_string *key;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data);
@@ -27982,72 +28121,81 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMPVAR_H
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
-unset_dim_again:
- if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht;
+ do {
+ if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ HashTable *ht;
+unset_dim_array:
+ SEPARATE_ARRAY(container);
+ ht = Z_ARRVAL_P(container);
offset_again:
- SEPARATE_ARRAY(container);
- ht = Z_ARRVAL_P(container);
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- zend_hash_index_del(ht, hval);
- break;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index_dim:
- zend_hash_index_del(ht, hval);
- break;
- case IS_STRING:
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ key = Z_STR_P(offset);
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
goto num_index_dim;
}
}
+str_index_dim:
if (ht == &EG(symbol_table)) {
- zend_delete_global_variable(Z_STR_P(offset));
+ zend_delete_global_variable(key);
} else {
- zend_hash_del(ht, Z_STR_P(offset));
+ zend_hash_del(ht, key);
}
- break;
- case IS_NULL:
- zend_hash_del(ht, STR_EMPTY_ALLOC());
- break;
- case IS_FALSE:
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index_dim:
+ zend_hash_index_del(ht, hval);
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto offset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_dim;
- case IS_TRUE:
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_dim;
- case IS_RESOURCE:
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
hval = Z_RES_HANDLE_P(offset);
goto num_index_dim;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto offset_again;
- break;
- default:
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else {
zend_error(E_WARNING, "Illegal offset type in unset");
- break;
+ }
+ break;
+ } else if (IS_UNUSED != IS_UNUSED && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto unset_dim_array;
+ }
}
- } else if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
- if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
- } else {
- Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
}
- } else if (IS_UNUSED != IS_UNUSED && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto unset_dim_again;
- } else if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- }
+ if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
+ } else {
+ Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ }
+ } else if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
+ }
+ } while (0);
+
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -28071,7 +28219,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_H
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -28120,12 +28267,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNU
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
-isset_dim_obj_again:
if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
zval *value;
zend_string *str;
+isset_dim_obj_array:
+ ht = Z_ARRVAL_P(container);
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
@@ -28140,31 +28288,31 @@ str_index_prop:
hval = Z_LVAL_P(offset);
num_index_prop:
value = zend_hash_index_find(ht, hval);
- } else {
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index_prop;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index_prop;
- case IS_FALSE:
- hval = 0;
- goto num_index_prop;
- case IS_TRUE:
- hval = 1;
- goto num_index_prop;
- case IS_RESOURCE:
- hval = Z_RES_HANDLE_P(offset);
- goto num_index_prop;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto isset_again;
- default:
- zend_error(E_WARNING, "Illegal offset type in isset or empty");
- value = NULL;
- break;
- }
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+ offset = Z_REFVAL_P(offset);
+ goto isset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ hval = Z_RES_HANDLE_P(offset);
+ goto num_index_prop;
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type in isset or empty");
+ goto isset_not_found;
}
if (opline->extended_value & ZEND_ISSET) {
@@ -28174,50 +28322,61 @@ num_index_prop:
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value));
}
- } else if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ goto isset_dim_obj_exit;
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto isset_dim_obj_array;
+ }
+ }
+
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ }
+
+ if (IS_UNUSED == IS_UNUSED ||
+ (IS_UNUSED != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
- result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
- result = 0;
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
+ goto isset_not_found;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
- zval tmp;
+ zend_long lval;
- result = 0;
- if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ lval = Z_LVAL_P(offset);
+isset_str_offset:
+ if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
+ if (opline->extended_value & ZEND_ISSET) {
+ result = 1;
+ } else {
+ result = (Z_STRVAL_P(container)[lval] == '0');
+ }
+ } else {
+ goto isset_not_found;
+ }
+ } else {
if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
- ZVAL_DUP(&tmp, offset);
- convert_to_long(&tmp);
- offset = &tmp;
- }
- }
- if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
- if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
- if ((opline->extended_value & ZEND_ISSET) ||
- Z_STRVAL_P(container)[offset->value.lval] != '0') {
- result = 1;
- }
+ lval = zval_get_long(offset);
+ goto isset_str_offset;
}
+ goto isset_not_found;
}
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
- } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto isset_dim_obj_again;
} else {
+isset_not_found:
result = ((opline->extended_value & ZEND_ISSET) == 0);
}
+isset_dim_obj_exit:
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, 1);
@@ -28245,7 +28404,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_UNUSED == IS_CONST ||
+ (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -28260,10 +28420,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN
isset_no_object:
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
- result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
}
zval_ptr_dtor_nogc(free_op2);
@@ -28323,7 +28482,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_O
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -28370,7 +28528,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_O
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -28417,7 +28574,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -28457,7 +28613,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -28493,7 +28648,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCO
zval *z;
SAVE_OPLINE();
- z = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ z = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
if (Z_TYPE_P(z) == IS_STRING) {
zend_string *str = Z_STR_P(z);
@@ -28506,6 +28661,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCO
if (str->len != 0) {
zend_write(str->val, str->len);
+ } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(z, BP_VAR_R);
}
zend_string_release(str);
}
@@ -28723,15 +28880,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OP
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
SAVE_OPLINE();
retval_ptr = GET_OP1_UNDEF_CV(retval_ptr, BP_VAR_R);
- CHECK_EXCEPTION();
- }
-
- if (!EX(return_value)) {
+ if (EX(return_value)) {
+ ZVAL_NULL(EX(return_value));
+ }
+ } else if (!EX(return_value)) {
if (IS_CV == IS_VAR || IS_CV == 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));
- CHECK_EXCEPTION();
}
}
} else {
@@ -28797,7 +28953,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(
if (IS_CV == IS_VAR && UNEXPECTED(retval_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot return string offsets by reference");
-
HANDLE_EXCEPTION();
}
@@ -28878,7 +29033,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPC
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ value = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
do {
if (IS_CV == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
@@ -28888,6 +29043,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPC
break;
}
}
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(value, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -28997,7 +29155,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_
if (IS_CV == IS_VAR && UNEXPECTED(varptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Only variables can be passed by reference");
-
HANDLE_EXCEPTION();
}
@@ -29157,7 +29314,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC
zend_object_clone_obj_t clone_call;
SAVE_OPLINE();
- obj = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ obj = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(obj) == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context");
@@ -29172,7 +29329,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC
if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) {
break;
}
- }
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(obj, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -29318,8 +29478,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO
}
}
} else {
- ZVAL_COPY_VALUE(result, expr);
- zval_opt_copy_ctor(result);
+ ZVAL_COPY(result, expr);
convert_to_object(result);
}
}
@@ -29339,10 +29498,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE
zend_bool failure_retval=0;
SAVE_OPLINE();
- inc_filename = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ inc_filename = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
ZVAL_UNDEF(&tmp_inc_filename);
if (Z_TYPE_P(inc_filename) != IS_STRING) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(inc_filename) == IS_UNDEF)) {
+ inc_filename = GET_OP1_UNDEF_CV(inc_filename, BP_VAR_R);
+ }
ZVAL_STR(&tmp_inc_filename, zval_get_string(inc_filename));
inc_filename = &tmp_inc_filename;
}
@@ -29958,13 +30120,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OP
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ value = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
try_strlen:
if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
} else {
zend_bool strict;
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+ value = GET_OP1_UNDEF_CV(value, BP_VAR_R);
+ }
if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
goto try_strlen;
@@ -30002,7 +30167,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CV_HANDLER(ZEN
SAVE_OPLINE();
value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) {
- if (UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+ if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
zend_class_entry *ce = Z_OBJCE_P(value);
if (UNEXPECTED(ce->name->len != sizeof("__PHP_Incomplete_Class") - 1) ||
@@ -30168,11 +30333,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- fast_div_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ fast_div_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -30222,11 +30388,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CONST_HANDLER(ZEND_
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_left_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ shift_left_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -30237,11 +30404,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_CONST_HANDLER(ZEND_
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_right_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ shift_right_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -30252,12 +30420,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- concat_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+
+ do {
+ if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+ (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+ zend_string *op1_str = Z_STR_P(op1);
+ zend_string *op2_str = Z_STR_P(op2);
+ zend_string *str;
+
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+ break;
+ }
+ }
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+
+ break;
+ }
+ }
+ if (IS_CV != IS_CONST && IS_CV != IS_CV &&
+ !IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+ size_t len = op1_str->len;
+
+ str = zend_string_realloc(op1_str, len + op2_str->len, 0);
+ memcpy(str->val + len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ break;
+ } else {
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ }
+ } else {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ concat_function(EX_VAR(opline->result.var), op1, op2);
+ }
+
+ } while (0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -30267,12 +30481,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CONST_HAN
{
USE_OPLINE
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ result = fast_is_identical_function(op1, op2);
ZEND_VM_SMART_BRANCH(result, (IS_CV|IS_CONST) & (IS_VAR|IS_TMP_VAR));
@@ -30287,12 +30502,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST
{
USE_OPLINE
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ result = fast_is_not_identical_function(op1, op2);
ZEND_VM_SMART_BRANCH(result, (IS_CV|IS_CONST) & (IS_VAR|IS_TMP_VAR));
@@ -30314,18 +30530,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -30357,10 +30573,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER
} while (0);
SAVE_OPLINE();
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -30383,18 +30599,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HAN
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -30426,10 +30642,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HAN
} while (0);
SAVE_OPLINE();
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -30547,12 +30763,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CONST_HANDLE
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2;
SAVE_OPLINE();
- compare_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ compare_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -30563,11 +30779,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CONST_HANDLER(ZE
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_or_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ bitwise_or_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -30578,11 +30795,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CONST_HANDLER(Z
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_and_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ bitwise_and_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -30593,11 +30811,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CONST_HANDLER(Z
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_xor_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ bitwise_xor_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -30608,11 +30827,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- boolean_xor_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -30644,7 +30864,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
-
HANDLE_EXCEPTION();
}
@@ -30674,42 +30893,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval *z;
- zval rv, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- if (Z_OBJ_HT(obj)->read_property &&
- (z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
- if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- zptr = z;
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- binary_op(z, z, value);
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- zval_ptr_dtor(zptr);
- } 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));
- }
- }
- OBJ_RELEASE(Z_OBJ(obj));
+ zend_assign_op_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -30741,7 +30925,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
-
HANDLE_EXCEPTION();
}
@@ -30811,7 +30994,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_C
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -31055,7 +31237,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_CONST_HA
#endif
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
@@ -31077,7 +31259,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -31098,51 +31279,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
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)) {
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
+ }
+ } else {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
+ }
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval rv;
-
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval *z, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- incdec_op(z);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(z);
- } else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- }
+ zend_pre_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -31153,15 +31310,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_CV_CONST(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_CV_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_CV_CONST(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_CV_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
@@ -31183,7 +31340,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -31202,44 +31358,25 @@ 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)) {
- ZVAL_DEREF(zptr);
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
- zval_opt_copy_ctor(zptr);
- incdec_op(zptr);
- } else {
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval rv, obj;
- zval *z;
- zval z_copy;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
}
- ZVAL_DUP(EX_VAR(opline->result.var), z);
- ZVAL_DUP(&z_copy, z);
- incdec_op(&z_copy);
- if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
- Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(&z_copy);
- zval_ptr_dtor(z);
} else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- ZVAL_NULL(EX_VAR(opline->result.var));
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ zval_opt_copy_ctor(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
}
+ } else {
+ zend_post_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var));
}
} while (0);
@@ -31250,12 +31387,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_CV_CONST(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_CV_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_CV_CONST(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return 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)
@@ -31268,7 +31405,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
HashTable *target_symbol_table;
SAVE_OPLINE();
- varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
if (IS_CV == IS_CONST) {
name = Z_STR_P(varname);
@@ -31276,6 +31413,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
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);
}
@@ -31468,7 +31608,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -31492,7 +31631,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HAN
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -31539,7 +31677,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CON
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -31576,7 +31713,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -31608,7 +31744,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HAND
offset = EX_CONSTANT(opline->op2);
- if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CV == IS_CONST ||
+ (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -31680,7 +31817,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
-
HANDLE_EXCEPTION();
}
@@ -31713,7 +31849,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HAN
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -31745,7 +31880,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HAN
offset = EX_CONSTANT(opline->op2);
- if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CV == IS_CONST ||
+ (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -31826,7 +31962,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CON
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -31862,7 +31997,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -31882,7 +32016,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_CONST_HANDL
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
try_fetch_list:
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
@@ -31894,7 +32028,8 @@ try_fetch_list:
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
+ } 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);
@@ -31906,10 +32041,13 @@ try_fetch_list:
} else {
ZVAL_NULL(result);
}
- } else if (Z_TYPE_P(container) == IS_REFERENCE) {
+ } 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));
}
CHECK_EXCEPTION();
@@ -31937,7 +32075,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
-
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));
@@ -31966,11 +32103,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDL
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
-
HANDLE_EXCEPTION();
}
-try_assign_dim:
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
try_assign_dim_array:
if (IS_CONST == IS_UNUSED) {
@@ -31998,53 +32133,58 @@ try_assign_dim_array:
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
}
- } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+ } 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);
+ 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, (opline+1)->op1_type, (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_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
- FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
+ } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+ if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ if (IS_CONST == IS_UNUSED) {
+ zend_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
+ FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- HANDLE_EXCEPTION();
- } else {
- zend_long offset;
+ HANDLE_EXCEPTION();
+ } else {
+ zend_long offset;
- dim = EX_CONSTANT(opline->op2);
- offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W);
+ dim = EX_CONSTANT(opline->op2);
+ offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W);
- value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ }
+ } 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)) {
+ if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) {
+ goto assign_dim_clean;
}
+ goto assign_dim_convert_to_array;
} 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_ISREF_P(object_ptr))) {
- object_ptr = Z_REFVAL_P(object_ptr);
- goto try_assign_dim;
- } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
- if (UNEXPECTED(object_ptr == &EG(error_zval))) {
- goto assign_dim_clean;
- }
- goto assign_dim_convert_to_array;
- } else {
- zend_error(E_WARNING, "Cannot use a scalar value as an array");
+ zend_error(E_WARNING, "Cannot use a scalar value as an array");
assign_dim_clean:
- dim = EX_CONSTANT(opline->op2);
+ dim = EX_CONSTANT(opline->op2);
- value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- FREE_OP(free_op_data1);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ FREE_OP(free_op_data1);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
}
}
@@ -32091,28 +32231,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND
zend_string *op1_str, *op2_str, *str;
SAVE_OPLINE();
- op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
- op2 = EX_CONSTANT(opline->op2);
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
if (IS_CV == IS_CONST) {
op1_str = Z_STR_P(op1);
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ op1_str = zend_string_copy(Z_STR_P(op1));
} else {
- op1_str = zval_get_string(op1);
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ op1_str = _zval_get_string_func(op1);
}
+ op2 = EX_CONSTANT(opline->op2);
if (IS_CONST == IS_CONST) {
op2_str = Z_STR_P(op2);
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ op2_str = zend_string_copy(Z_STR_P(op2));
} else {
- op2_str = zval_get_string(op2);
- }
- str = zend_string_alloc(op1_str->len + op2_str->len, 0);
- memcpy(str->val, op1_str->val, op1_str->len);
- memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
- ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
- if (IS_CV != IS_CONST) {
- zend_string_release(op1_str);
- }
- if (IS_CONST != IS_CONST) {
- zend_string_release(op2_str);
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ op2_str = _zval_get_string_func(op2);
}
+ do {
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ if (IS_CONST == IS_CONST) {
+ zend_string_addref(op2_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+ zend_string_release(op1_str);
+ break;
+ }
+ }
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ if (IS_CV == IS_CONST) {
+ zend_string_addref(op1_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+ zend_string_release(op2_str);
+ break;
+ }
+ }
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ if (IS_CV != IS_CONST) {
+ zend_string_release(op1_str);
+ }
+ if (IS_CONST != IS_CONST) {
+ zend_string_release(op2_str);
+ }
+ } while (0);
CHECK_EXCEPTION();
@@ -32144,6 +32316,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST
break;
}
}
+ 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();
}
@@ -32154,7 +32329,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST
} while (0);
}
- object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ object = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context");
@@ -32164,13 +32339,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST
if (IS_CV != IS_UNUSED) {
do {
- if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (IS_CV == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
break;
}
}
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(object, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -32217,7 +32395,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
- } else if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+ } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+ /* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@@ -32243,18 +32422,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEN
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -32285,10 +32464,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEN
} while (0);
SAVE_OPLINE();
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -32307,11 +32486,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONS
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ 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_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
-
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -32321,11 +32499,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONS
} else {
expr_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
if (IS_CV == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_CV == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_CV == IS_CV) {
@@ -32356,43 +32534,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONS
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if (IS_CONST != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if (IS_CONST != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
} else {
@@ -32463,10 +32639,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLE
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ 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;
}
@@ -32519,6 +32698,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLE
zval *container;
zval *offset;
zend_ulong hval;
+ zend_string *key;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var);
@@ -32530,72 +32710,80 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
-
HANDLE_EXCEPTION();
}
offset = EX_CONSTANT(opline->op2);
-unset_dim_again:
- if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht;
+ do {
+ if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ HashTable *ht;
+unset_dim_array:
+ SEPARATE_ARRAY(container);
+ ht = Z_ARRVAL_P(container);
offset_again:
- SEPARATE_ARRAY(container);
- ht = Z_ARRVAL_P(container);
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- zend_hash_index_del(ht, hval);
- break;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index_dim:
- zend_hash_index_del(ht, hval);
- break;
- case IS_STRING:
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ key = Z_STR_P(offset);
if (IS_CONST != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
goto num_index_dim;
}
}
+str_index_dim:
if (ht == &EG(symbol_table)) {
- zend_delete_global_variable(Z_STR_P(offset));
+ zend_delete_global_variable(key);
} else {
- zend_hash_del(ht, Z_STR_P(offset));
+ zend_hash_del(ht, key);
}
- break;
- case IS_NULL:
- zend_hash_del(ht, STR_EMPTY_ALLOC());
- break;
- case IS_FALSE:
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index_dim:
+ zend_hash_index_del(ht, hval);
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto offset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_dim;
- case IS_TRUE:
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_dim;
- case IS_RESOURCE:
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
hval = Z_RES_HANDLE_P(offset);
goto num_index_dim;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto offset_again;
- break;
- default:
+ } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else {
zend_error(E_WARNING, "Illegal offset type in unset");
- break;
+ }
+ break;
+ } else if (IS_CV != IS_UNUSED && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto unset_dim_array;
+ }
}
- } else if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
- if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
- } else {
- Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
}
- } else if (IS_CV != IS_UNUSED && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto unset_dim_again;
- } else if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- }
+ if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
+ } else {
+ Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ }
+ } else if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
+ }
+ } while (0);
CHECK_EXCEPTION();
@@ -32619,7 +32807,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
-
HANDLE_EXCEPTION();
}
offset = EX_CONSTANT(opline->op2);
@@ -32772,12 +32959,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_
offset = EX_CONSTANT(opline->op2);
-isset_dim_obj_again:
if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
zval *value;
zend_string *str;
+isset_dim_obj_array:
+ ht = Z_ARRVAL_P(container);
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
@@ -32792,31 +32980,31 @@ str_index_prop:
hval = Z_LVAL_P(offset);
num_index_prop:
value = zend_hash_index_find(ht, hval);
- } else {
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index_prop;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index_prop;
- case IS_FALSE:
- hval = 0;
- goto num_index_prop;
- case IS_TRUE:
- hval = 1;
- goto num_index_prop;
- case IS_RESOURCE:
- hval = Z_RES_HANDLE_P(offset);
- goto num_index_prop;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto isset_again;
- default:
- zend_error(E_WARNING, "Illegal offset type in isset or empty");
- value = NULL;
- break;
- }
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+ offset = Z_REFVAL_P(offset);
+ goto isset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ hval = Z_RES_HANDLE_P(offset);
+ goto num_index_prop;
+ } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type in isset or empty");
+ goto isset_not_found;
}
if (opline->extended_value & ZEND_ISSET) {
@@ -32826,50 +33014,62 @@ num_index_prop:
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value));
}
- } else if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ goto isset_dim_obj_exit;
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto isset_dim_obj_array;
+ }
+ }
+
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ }
+
+ if (IS_CV == IS_UNUSED ||
+ (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
- result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
- result = 0;
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
+ goto isset_not_found;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
- zval tmp;
+ zend_long lval;
- result = 0;
- if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ lval = Z_LVAL_P(offset);
+isset_str_offset:
+ if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
+ if (opline->extended_value & ZEND_ISSET) {
+ result = 1;
+ } else {
+ result = (Z_STRVAL_P(container)[lval] == '0');
+ }
+ } else {
+ goto isset_not_found;
+ }
+ } else {
if (IS_CONST & (IS_CV|IS_VAR)) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
- ZVAL_DUP(&tmp, offset);
- convert_to_long(&tmp);
- offset = &tmp;
- }
- }
- if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
- if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
- if ((opline->extended_value & ZEND_ISSET) ||
- Z_STRVAL_P(container)[offset->value.lval] != '0') {
- result = 1;
- }
+ lval = zval_get_long(offset);
+ goto isset_str_offset;
}
+ goto isset_not_found;
}
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
- } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto isset_dim_obj_again;
} else {
+isset_not_found:
result = ((opline->extended_value & ZEND_ISSET) == 0);
}
+isset_dim_obj_exit:
+
ZEND_VM_SMART_BRANCH(result, 1);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
@@ -32896,7 +33096,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV
offset = EX_CONSTANT(opline->op2);
- if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CV == IS_CONST ||
+ (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -32911,10 +33112,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV
isset_no_object:
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
- result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
}
@@ -32932,7 +33132,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_CONST_HANDL
zend_bool result;
SAVE_OPLINE();
- expr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ expr = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
try_instanceof:
if (Z_TYPE_P(expr) == IS_OBJECT) {
@@ -32959,6 +33159,9 @@ try_instanceof:
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;
}
@@ -32975,7 +33178,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
@@ -32992,7 +33195,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE
if (IS_CV != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -33002,11 +33205,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE
value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_CV != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var);
@@ -33014,7 +33216,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE
if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
-
HANDLE_EXCEPTION();
}
@@ -33036,11 +33237,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE
/* Consts, temporary variables and references need copying */
if (IS_CV == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -33061,11 +33265,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE
/* Consts, temporary variables and references need copying */
if (IS_CONST == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -33109,11 +33316,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_CONST_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- pow_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ pow_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -33210,12 +33418,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDL
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_CV|IS_TMP_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -33230,12 +33439,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_H
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_CV|IS_TMP_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -33282,7 +33492,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
@@ -33299,7 +33509,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND
if (IS_CV != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -33309,11 +33519,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND
value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_CV != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var);
@@ -33321,7 +33530,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND
if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-
HANDLE_EXCEPTION();
}
@@ -33343,11 +33551,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND
/* Consts, temporary variables and references need copying */
if (IS_CV == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -33368,11 +33579,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND
/* Consts, temporary variables and references need copying */
if (IS_TMP_VAR == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -33416,12 +33630,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDL
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_CV|IS_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -33436,12 +33651,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_H
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, (IS_CV|IS_VAR) & (IS_VAR|IS_TMP_VAR));
@@ -33462,7 +33678,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
HashTable *target_symbol_table;
SAVE_OPLINE();
- varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
if (IS_CV == IS_CONST) {
name = Z_STR_P(varname);
@@ -33470,6 +33686,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
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);
}
@@ -33677,7 +33896,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER
if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- if (free_op2) {zval_ptr_dtor_nogc(free_op2);};
HANDLE_EXCEPTION();
}
@@ -33700,7 +33918,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
if (free_op2) {zval_ptr_dtor_nogc(free_op2);};
-
HANDLE_EXCEPTION();
}
if (IS_CV == IS_VAR &&
@@ -33758,10 +33975,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ 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;
}
@@ -33920,7 +34140,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER
zend_bool result;
SAVE_OPLINE();
- expr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ expr = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
try_instanceof:
if (Z_TYPE_P(expr) == IS_OBJECT) {
@@ -33947,6 +34167,9 @@ try_instanceof:
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;
}
@@ -33963,7 +34186,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
@@ -33980,7 +34203,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND
if (IS_CV != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -33990,11 +34213,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND
value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_CV != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var);
@@ -34002,7 +34224,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND
if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-
HANDLE_EXCEPTION();
}
@@ -34024,11 +34245,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND
/* Consts, temporary variables and references need copying */
if (IS_CV == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -34049,11 +34273,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND
/* Consts, temporary variables and references need copying */
if (IS_VAR == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
zval_ptr_dtor_nogc(free_op2);
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -34112,7 +34339,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
-
HANDLE_EXCEPTION();
}
@@ -34398,7 +34624,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
HashTable *target_symbol_table;
SAVE_OPLINE();
- varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
if (IS_CV == IS_CONST) {
name = Z_STR_P(varname);
@@ -34406,6 +34632,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
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);
}
@@ -34583,7 +34812,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HAN
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
-
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED);
@@ -34607,7 +34835,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
-
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED);
@@ -34639,7 +34866,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNU
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
-
HANDLE_EXCEPTION();
}
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED);
@@ -34681,11 +34907,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HAND
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
-
HANDLE_EXCEPTION();
}
-try_assign_dim:
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
try_assign_dim_array:
if (IS_UNUSED == IS_UNUSED) {
@@ -34713,53 +34937,58 @@ try_assign_dim_array:
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
}
- } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+ } 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;
+ 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, (opline+1)->op1_type, (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_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
- FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
+ } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+ if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ if (IS_UNUSED == IS_UNUSED) {
+ zend_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
+ FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- HANDLE_EXCEPTION();
- } else {
- zend_long offset;
+ HANDLE_EXCEPTION();
+ } else {
+ zend_long offset;
- dim = NULL;
- offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W);
+ dim = NULL;
+ offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W);
- value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ }
+ } 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)) {
+ if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) {
+ goto assign_dim_clean;
+ }
+ goto assign_dim_convert_to_array;
} 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_ISREF_P(object_ptr))) {
- object_ptr = Z_REFVAL_P(object_ptr);
- goto try_assign_dim;
- } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
- if (UNEXPECTED(object_ptr == &EG(error_zval))) {
- goto assign_dim_clean;
- }
- goto assign_dim_convert_to_array;
- } else {
- zend_error(E_WARNING, "Cannot use a scalar value as an array");
+ zend_error(E_WARNING, "Cannot use a scalar value as an array");
assign_dim_clean:
- dim = NULL;
+ dim = NULL;
- value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- FREE_OP(free_op_data1);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ FREE_OP(free_op_data1);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
}
}
@@ -34812,6 +35041,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU
}
}
zend_verify_return_type(EX(func), retval_ptr);
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ }
#endif
}
CHECK_EXCEPTION();
@@ -34826,11 +35059,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUS
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ 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_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
-
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -34840,11 +35072,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUS
} else {
expr_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
if (IS_CV == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_CV == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_CV == IS_CV) {
@@ -34875,43 +35107,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUS
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if (IS_UNUSED != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if (IS_UNUSED != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
} else {
@@ -34982,10 +35212,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDL
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ 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;
}
@@ -35143,7 +35376,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
@@ -35160,7 +35393,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z
if (IS_CV != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -35170,11 +35403,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z
value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_CV != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var);
@@ -35182,7 +35414,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z
if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
-
HANDLE_EXCEPTION();
}
@@ -35204,11 +35435,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z
/* Consts, temporary variables and references need copying */
if (IS_CV == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -35229,11 +35463,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z
/* Consts, temporary variables and references need copying */
if (IS_UNUSED == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -35412,11 +35649,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OP
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- fast_div_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ fast_div_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -35466,11 +35704,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CV_HANDLER(ZEND_OPC
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_left_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ shift_left_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -35481,11 +35720,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_CV_HANDLER(ZEND_OPC
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_right_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ shift_right_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -35496,12 +35736,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- concat_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+
+ do {
+ if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+ (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+ zend_string *op1_str = Z_STR_P(op1);
+ zend_string *op2_str = Z_STR_P(op2);
+ zend_string *str;
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+
+ break;
+ }
+ }
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+
+ break;
+ }
+ }
+ if (IS_CV != IS_CONST && IS_CV != IS_CV &&
+ !IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+ size_t len = op1_str->len;
+
+ str = zend_string_realloc(op1_str, len + op2_str->len, 0);
+ memcpy(str->val + len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ break;
+ } else {
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ }
+ } else {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ concat_function(EX_VAR(opline->result.var), op1, op2);
+ }
+
+ } while (0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -35511,12 +35797,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLE
{
USE_OPLINE
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_identical_function(
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ result = fast_is_identical_function(op1, op2);
ZEND_VM_SMART_BRANCH(result, (IS_CV|IS_CV) & (IS_VAR|IS_TMP_VAR));
@@ -35531,12 +35818,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HA
{
USE_OPLINE
+ zval *op1, *op2;
int result;
SAVE_OPLINE();
- result = fast_is_not_identical_function(
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ result = fast_is_not_identical_function(op1, op2);
ZEND_VM_SMART_BRANCH(result, (IS_CV|IS_CV) & (IS_VAR|IS_TMP_VAR));
@@ -35558,18 +35846,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZE
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -35601,10 +35889,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZE
} while (0);
SAVE_OPLINE();
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -35627,18 +35915,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLE
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -35670,10 +35958,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLE
} while (0);
SAVE_OPLINE();
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -35791,12 +36079,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CV_HANDLER(Z
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2;
SAVE_OPLINE();
- compare_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ compare_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -35807,11 +36095,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CV_HANDLER(ZEND_
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_or_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ bitwise_or_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -35822,11 +36111,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CV_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_and_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ bitwise_and_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -35837,11 +36127,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CV_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_xor_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ bitwise_xor_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -35852,11 +36143,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER(ZE
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- boolean_xor_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -35888,7 +36180,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
-
HANDLE_EXCEPTION();
}
@@ -35918,42 +36209,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval *z;
- zval rv, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- if (Z_OBJ_HT(obj)->read_property &&
- (z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
- if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- zptr = z;
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- binary_op(z, z, value);
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- zval_ptr_dtor(zptr);
- } 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));
- }
- }
- OBJ_RELEASE(Z_OBJ(obj));
+ zend_assign_op_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -35985,7 +36241,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
-
HANDLE_EXCEPTION();
}
@@ -36055,7 +36310,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_C
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -36299,7 +36553,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_CV_HANDL
#endif
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
@@ -36321,7 +36575,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -36342,51 +36595,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
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)) {
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
+ }
+ } else {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
+ }
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval rv;
-
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval *z, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- incdec_op(z);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(z);
- } else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- }
+ zend_pre_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -36397,15 +36626,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_CV_CV(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_CV_CV(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_CV_CV(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_CV_CV(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
@@ -36427,7 +36656,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
-
HANDLE_EXCEPTION();
}
@@ -36446,44 +36674,25 @@ 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)) {
- ZVAL_DEREF(zptr);
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
- zval_opt_copy_ctor(zptr);
- incdec_op(zptr);
- } else {
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval rv, obj;
- zval *z;
- zval z_copy;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
}
- ZVAL_DUP(EX_VAR(opline->result.var), z);
- ZVAL_DUP(&z_copy, z);
- incdec_op(&z_copy);
- if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
- Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(&z_copy);
- zval_ptr_dtor(z);
} else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- ZVAL_NULL(EX_VAR(opline->result.var));
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ zval_opt_copy_ctor(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
}
+ } else {
+ zend_post_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var));
}
} while (0);
@@ -36494,12 +36703,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_CV_CV(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_CV_CV(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_CV_CV(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_CV_CV(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -36528,7 +36737,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -36552,7 +36760,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -36599,7 +36806,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -36636,7 +36842,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HAN
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -36668,7 +36873,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CV == IS_CONST ||
+ (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -36740,7 +36946,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
-
HANDLE_EXCEPTION();
}
@@ -36773,7 +36978,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -36805,7 +37009,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLE
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CV == IS_CONST ||
+ (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -36886,7 +37091,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -36922,7 +37126,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HAN
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -36956,7 +37159,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER(
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
-
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));
@@ -36985,11 +37187,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
-
HANDLE_EXCEPTION();
}
-try_assign_dim:
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
try_assign_dim_array:
if (IS_CV == IS_UNUSED) {
@@ -37017,53 +37217,58 @@ try_assign_dim_array:
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
}
- } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+ } 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);
+ 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, (opline+1)->op1_type, (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_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
- FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
+ } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+ if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ if (IS_CV == IS_UNUSED) {
+ zend_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
+ FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- HANDLE_EXCEPTION();
- } else {
- zend_long offset;
+ 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);
+ 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_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ }
+ } 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)) {
+ if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) {
+ goto assign_dim_clean;
+ }
+ goto assign_dim_convert_to_array;
} 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_ISREF_P(object_ptr))) {
- object_ptr = Z_REFVAL_P(object_ptr);
- goto try_assign_dim;
- } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
- if (UNEXPECTED(object_ptr == &EG(error_zval))) {
- goto assign_dim_clean;
- }
- goto assign_dim_convert_to_array;
- } else {
- zend_error(E_WARNING, "Cannot use a scalar value as an array");
+ zend_error(E_WARNING, "Cannot use a scalar value as an array");
assign_dim_clean:
- dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- FREE_OP(free_op_data1);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ FREE_OP(free_op_data1);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
}
}
@@ -37115,7 +37320,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(
if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
-
HANDLE_EXCEPTION();
}
if (IS_CV == IS_VAR &&
@@ -37137,7 +37341,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
-
HANDLE_EXCEPTION();
}
if (IS_CV == IS_VAR &&
@@ -37172,28 +37375,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER
zend_string *op1_str, *op2_str, *str;
SAVE_OPLINE();
- op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
- op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
if (IS_CV == IS_CONST) {
op1_str = Z_STR_P(op1);
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ op1_str = zend_string_copy(Z_STR_P(op1));
} else {
- op1_str = zval_get_string(op1);
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ op1_str = _zval_get_string_func(op1);
}
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
if (IS_CV == IS_CONST) {
op2_str = Z_STR_P(op2);
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ op2_str = zend_string_copy(Z_STR_P(op2));
} else {
- op2_str = zval_get_string(op2);
- }
- str = zend_string_alloc(op1_str->len + op2_str->len, 0);
- memcpy(str->val, op1_str->val, op1_str->len);
- memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
- ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
- if (IS_CV != IS_CONST) {
- zend_string_release(op1_str);
- }
- if (IS_CV != IS_CONST) {
- zend_string_release(op2_str);
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ op2_str = _zval_get_string_func(op2);
}
+ do {
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ if (IS_CV == IS_CONST) {
+ zend_string_addref(op2_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+ zend_string_release(op1_str);
+ break;
+ }
+ }
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ if (IS_CV == IS_CONST) {
+ zend_string_addref(op1_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+ zend_string_release(op2_str);
+ break;
+ }
+ }
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ if (IS_CV != IS_CONST) {
+ zend_string_release(op1_str);
+ }
+ if (IS_CV != IS_CONST) {
+ zend_string_release(op2_str);
+ }
+ } while (0);
CHECK_EXCEPTION();
@@ -37214,7 +37449,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA
SAVE_OPLINE();
- function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ function_name = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
@@ -37225,6 +37460,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA
break;
}
}
+ 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();
}
@@ -37235,7 +37473,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA
} while (0);
}
- object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ object = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context");
@@ -37245,13 +37483,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA
if (IS_CV != IS_UNUSED) {
do {
- if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (IS_CV == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
break;
}
}
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(object, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -37298,7 +37539,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
- } else if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+ } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+ /* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@@ -37324,18 +37566,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_O
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -37366,10 +37608,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_O
} while (0);
SAVE_OPLINE();
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -37388,11 +37630,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_H
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ 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_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
-
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -37402,11 +37643,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_H
} else {
expr_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
if (IS_CV == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_CV == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_CV == IS_CV) {
@@ -37432,48 +37673,46 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_H
if (IS_CV != IS_UNUSED) {
- zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ zval *offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
zend_string *str;
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if (IS_CV != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if (IS_CV != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
} else {
@@ -37521,6 +37760,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(Z
zval *container;
zval *offset;
zend_ulong hval;
+ zend_string *key;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var);
@@ -37532,72 +37772,80 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(Z
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
-
HANDLE_EXCEPTION();
}
- offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
-unset_dim_again:
- if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht;
+ do {
+ if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ HashTable *ht;
+unset_dim_array:
+ SEPARATE_ARRAY(container);
+ ht = Z_ARRVAL_P(container);
offset_again:
- SEPARATE_ARRAY(container);
- ht = Z_ARRVAL_P(container);
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- zend_hash_index_del(ht, hval);
- break;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index_dim:
- zend_hash_index_del(ht, hval);
- break;
- case IS_STRING:
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ key = Z_STR_P(offset);
if (IS_CV != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
goto num_index_dim;
}
}
+str_index_dim:
if (ht == &EG(symbol_table)) {
- zend_delete_global_variable(Z_STR_P(offset));
+ zend_delete_global_variable(key);
} else {
- zend_hash_del(ht, Z_STR_P(offset));
+ zend_hash_del(ht, key);
}
- break;
- case IS_NULL:
- zend_hash_del(ht, STR_EMPTY_ALLOC());
- break;
- case IS_FALSE:
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index_dim:
+ zend_hash_index_del(ht, hval);
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto offset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_dim;
- case IS_TRUE:
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_dim;
- case IS_RESOURCE:
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
hval = Z_RES_HANDLE_P(offset);
goto num_index_dim;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto offset_again;
- break;
- default:
+ } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else {
zend_error(E_WARNING, "Illegal offset type in unset");
- break;
+ }
+ break;
+ } else if (IS_CV != IS_UNUSED && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto unset_dim_array;
+ }
}
- } else if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
- if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
- } else {
- Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
}
- } else if (IS_CV != IS_UNUSED && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto unset_dim_again;
- } else if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- }
+ if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
+ } else {
+ Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ }
+ } else if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
+ }
+ } while (0);
CHECK_EXCEPTION();
@@ -37621,7 +37869,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(Z
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
-
HANDLE_EXCEPTION();
}
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
@@ -37667,14 +37914,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_
HANDLE_EXCEPTION();
}
- offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
-isset_dim_obj_again:
if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
zval *value;
zend_string *str;
+isset_dim_obj_array:
+ ht = Z_ARRVAL_P(container);
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
@@ -37689,31 +37937,31 @@ str_index_prop:
hval = Z_LVAL_P(offset);
num_index_prop:
value = zend_hash_index_find(ht, hval);
- } else {
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index_prop;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index_prop;
- case IS_FALSE:
- hval = 0;
- goto num_index_prop;
- case IS_TRUE:
- hval = 1;
- goto num_index_prop;
- case IS_RESOURCE:
- hval = Z_RES_HANDLE_P(offset);
- goto num_index_prop;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto isset_again;
- default:
- zend_error(E_WARNING, "Illegal offset type in isset or empty");
- value = NULL;
- break;
- }
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+ offset = Z_REFVAL_P(offset);
+ goto isset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ hval = Z_RES_HANDLE_P(offset);
+ goto num_index_prop;
+ } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type in isset or empty");
+ goto isset_not_found;
}
if (opline->extended_value & ZEND_ISSET) {
@@ -37723,50 +37971,62 @@ num_index_prop:
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value));
}
- } else if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ goto isset_dim_obj_exit;
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto isset_dim_obj_array;
+ }
+ }
+
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ }
+
+ if (IS_CV == IS_UNUSED ||
+ (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
- result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
- result = 0;
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
+ goto isset_not_found;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
- zval tmp;
+ zend_long lval;
- result = 0;
- if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ lval = Z_LVAL_P(offset);
+isset_str_offset:
+ if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
+ if (opline->extended_value & ZEND_ISSET) {
+ result = 1;
+ } else {
+ result = (Z_STRVAL_P(container)[lval] == '0');
+ }
+ } else {
+ goto isset_not_found;
+ }
+ } else {
if (IS_CV & (IS_CV|IS_VAR)) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
- ZVAL_DUP(&tmp, offset);
- convert_to_long(&tmp);
- offset = &tmp;
- }
- }
- if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
- if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
- if ((opline->extended_value & ZEND_ISSET) ||
- Z_STRVAL_P(container)[offset->value.lval] != '0') {
- result = 1;
- }
+ lval = zval_get_long(offset);
+ goto isset_str_offset;
}
+ goto isset_not_found;
}
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
- } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto isset_dim_obj_again;
} else {
+isset_not_found:
result = ((opline->extended_value & ZEND_ISSET) == 0);
}
+isset_dim_obj_exit:
+
ZEND_VM_SMART_BRANCH(result, 1);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
@@ -37793,7 +38053,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CV == IS_CONST ||
+ (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -37808,10 +38069,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV
isset_no_object:
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
- result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
}
@@ -37828,7 +38088,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_
zend_generator *generator = zend_get_running_generator(execute_data);
SAVE_OPLINE();
- if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");
@@ -37845,7 +38105,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_
if (IS_CV != IS_UNUSED) {
- if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ 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) {
@@ -37855,11 +38115,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_
value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
ZVAL_COPY_VALUE(&generator->value, value);
- if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
-
- /* Temporary variables don't need ctor copying */
- if (IS_CV != IS_TMP_VAR) {
- zval_opt_copy_ctor(&generator->value);
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
}
} else {
zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var);
@@ -37867,7 +38126,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_
if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot yield string offsets by reference");
-
HANDLE_EXCEPTION();
}
@@ -37889,11 +38147,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_
/* Consts, temporary variables and references need copying */
if (IS_CV == IS_CONST) {
- ZVAL_DUP(&generator->value, value);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->value))) {
+ zval_copy_ctor_func(&generator->value);
+ }
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
- ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
} else {
ZVAL_COPY_VALUE(&generator->value, value);
@@ -37914,11 +38175,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_
/* Consts, temporary variables and references need copying */
if (IS_CV == IS_CONST) {
- ZVAL_DUP(&generator->key, key);
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_COPYABLE(generator->key))) {
+ zval_copy_ctor_func(&generator->key);
+ }
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
- ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
} else {
ZVAL_COPY_VALUE(&generator->key, key);
@@ -37962,11 +38226,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_CV_HANDLER(ZEND_OP
{
USE_OPLINE
+ zval *op1, *op2;
SAVE_OPLINE();
- pow_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ pow_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -38117,11 +38382,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_TMPVAR_HANDLER(ZEN
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- fast_div_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ fast_div_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -38171,11 +38437,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_TMPVAR_HANDLER(ZEND
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_left_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ shift_left_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -38186,11 +38453,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_TMPVAR_HANDLER(ZEND
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_right_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ shift_right_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -38201,12 +38469,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- concat_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+
+ do {
+ if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+ ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+ zend_string *op1_str = Z_STR_P(op1);
+ zend_string *op2_str = Z_STR_P(op2);
+ zend_string *str;
+
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+ break;
+ }
+ }
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+
+ break;
+ }
+ }
+ if (IS_CV != IS_CONST && IS_CV != IS_CV &&
+ !IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+ size_t len = op1_str->len;
+
+ str = zend_string_realloc(op1_str, len + op2_str->len, 0);
+ memcpy(str->val + len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ break;
+ } else {
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ }
+ } else {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ concat_function(EX_VAR(opline->result.var), op1, op2);
+ }
+
+ } while (0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -38223,18 +38537,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLE
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -38266,10 +38580,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLE
} while (0);
SAVE_OPLINE();
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -38292,18 +38606,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HA
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -38335,10 +38649,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HA
} while (0);
SAVE_OPLINE();
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -38456,12 +38770,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDL
{
USE_OPLINE
zend_free_op free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2;
SAVE_OPLINE();
- compare_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ compare_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -38472,11 +38786,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_TMPVAR_HANDLER(Z
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_or_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ bitwise_or_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -38487,11 +38802,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_TMPVAR_HANDLER(
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_and_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ bitwise_and_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -38502,11 +38818,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_TMPVAR_HANDLER(
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_xor_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ bitwise_xor_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -38517,11 +38834,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLE
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- boolean_xor_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -38553,7 +38871,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "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();
}
@@ -38583,42 +38900,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval *z;
- zval rv, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- if (Z_OBJ_HT(obj)->read_property &&
- (z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
- if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- zptr = z;
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- binary_op(z, z, value);
- Z_OBJ_HT(obj)->write_property(&obj, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- zval_ptr_dtor(zptr);
- } 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));
- }
- }
- OBJ_RELEASE(Z_OBJ(obj));
+ zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -38650,7 +38932,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP
zend_error(E_EXCEPTION | E_ERROR, "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();
}
@@ -38721,7 +39002,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_C
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
zval_ptr_dtor_nogc(free_op2);
-
HANDLE_EXCEPTION();
}
@@ -38966,7 +39246,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_H
#endif
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
zend_free_op free_op2;
@@ -38988,7 +39268,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
zval_ptr_dtor_nogc(free_op2);
-
HANDLE_EXCEPTION();
}
@@ -39009,51 +39288,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
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)) {
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
+ }
+ } else {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
+ }
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval rv;
-
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval *z, obj;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
-
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
- }
- ZVAL_DEREF(z);
- SEPARATE_ZVAL_NOREF(z);
- incdec_op(z);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), z);
- }
- Z_OBJ_HT(obj)->write_property(&obj, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(z);
- } else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- }
+ zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
} while (0);
@@ -39065,15 +39320,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMPVAR(incdec_t incdec_op ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
zend_free_op free_op2;
@@ -39095,7 +39350,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
zval_ptr_dtor_nogc(free_op2);
-
HANDLE_EXCEPTION();
}
@@ -39114,44 +39368,25 @@ 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)) {
- ZVAL_DEREF(zptr);
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
- zval_opt_copy_ctor(zptr);
- incdec_op(zptr);
- } else {
- if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
- zval rv, obj;
- zval *z;
- zval z_copy;
-
- ZVAL_OBJ(&obj, Z_OBJ_P(object));
- Z_ADDREF(obj);
- z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
- if (UNEXPECTED(EG(exception))) {
- OBJ_RELEASE(Z_OBJ(obj));
- break;
- }
-
- if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
- zval rv2;
- zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
- if (z == &rv) {
- zval_ptr_dtor(&rv);
- }
- ZVAL_COPY_VALUE(z, value);
+ if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ if (inc) {
+ fast_long_increment_function(zptr);
+ } else {
+ fast_long_decrement_function(zptr);
}
- ZVAL_DUP(EX_VAR(opline->result.var), z);
- ZVAL_DUP(&z_copy, z);
- incdec_op(&z_copy);
- if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
- Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
- OBJ_RELEASE(Z_OBJ(obj));
- zval_ptr_dtor(&z_copy);
- zval_ptr_dtor(z);
} else {
- zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
- ZVAL_NULL(EX_VAR(opline->result.var));
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
+ zval_opt_copy_ctor(zptr);
+ if (inc) {
+ increment_function(zptr);
+ } else {
+ decrement_function(zptr);
+ }
}
+ } else {
+ zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var));
}
} while (0);
@@ -39163,12 +39398,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_CV_TMPVAR(increment_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_CV_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_post_incdec_property_helper_SPEC_CV_TMPVAR(decrement_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
+ return zend_post_incdec_property_helper_SPEC_CV_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -39197,7 +39432,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HAN
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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));
@@ -39221,7 +39455,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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));
@@ -39268,7 +39501,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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));
@@ -39305,7 +39537,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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));
@@ -39337,7 +39568,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CV == IS_CONST ||
+ (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -39410,7 +39642,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HAN
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");
zval_ptr_dtor_nogc(free_op2);
-
HANDLE_EXCEPTION();
}
@@ -39443,7 +39674,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -39475,7 +39705,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CV == IS_CONST ||
+ (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -39557,7 +39788,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -39593,7 +39823,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -39627,7 +39856,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_HAND
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array");
zval_ptr_dtor_nogc(free_op2);
-
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));
@@ -39656,11 +39884,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_HAND
zend_error(E_EXCEPTION | E_ERROR, "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();
}
-try_assign_dim:
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
try_assign_dim_array:
if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
@@ -39688,53 +39914,58 @@ try_assign_dim_array:
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
}
- } else 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);
+ } 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, (opline+1)->op1_type, (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_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
- FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.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);
+ 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_error(E_EXCEPTION | E_ERROR, "[] operator not supported for strings");
+ FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
- HANDLE_EXCEPTION();
- } else {
- zend_long offset;
+ 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_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ 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_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, 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);
+ }
+ } 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)) {
+ if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) {
+ goto assign_dim_clean;
}
+ goto assign_dim_convert_to_array;
} 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_ISREF_P(object_ptr))) {
- object_ptr = Z_REFVAL_P(object_ptr);
- goto try_assign_dim;
- } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
- if (UNEXPECTED(object_ptr == &EG(error_zval))) {
- goto assign_dim_clean;
- }
- goto assign_dim_convert_to_array;
- } else {
- zend_error(E_WARNING, "Cannot use a scalar value as an array");
+ zend_error(E_WARNING, "Cannot use a scalar value as an array");
assign_dim_clean:
- dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- zval_ptr_dtor_nogc(free_op2);
- value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- FREE_OP(free_op_data1);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ zval_ptr_dtor_nogc(free_op2);
+ value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ FREE_OP(free_op_data1);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
}
}
@@ -39752,28 +39983,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
zend_string *op1_str, *op2_str, *str;
SAVE_OPLINE();
- op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
- op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
if (IS_CV == IS_CONST) {
op1_str = Z_STR_P(op1);
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ op1_str = zend_string_copy(Z_STR_P(op1));
} else {
- op1_str = zval_get_string(op1);
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ op1_str = _zval_get_string_func(op1);
}
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
op2_str = Z_STR_P(op2);
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ op2_str = zend_string_copy(Z_STR_P(op2));
} else {
- op2_str = zval_get_string(op2);
- }
- str = zend_string_alloc(op1_str->len + op2_str->len, 0);
- memcpy(str->val, op1_str->val, op1_str->len);
- memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
- ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
- if (IS_CV != IS_CONST) {
- zend_string_release(op1_str);
- }
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- zend_string_release(op2_str);
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ op2_str = _zval_get_string_func(op2);
}
+ do {
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+ zend_string_addref(op2_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+ zend_string_release(op1_str);
+ break;
+ }
+ }
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ if (IS_CV == IS_CONST) {
+ zend_string_addref(op1_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+ zend_string_release(op2_str);
+ break;
+ }
+ }
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ if (IS_CV != IS_CONST) {
+ zend_string_release(op1_str);
+ }
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ zend_string_release(op2_str);
+ }
+ } while (0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -39805,6 +40068,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
break;
}
}
+ 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();
}
@@ -39815,7 +40081,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
} while (0);
}
- object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ object = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context");
@@ -39825,13 +40091,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
if (IS_CV != IS_UNUSED) {
do {
- if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (IS_CV == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
break;
}
}
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(object, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -39878,7 +40147,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
- } else if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+ } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+ /* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@@ -39905,18 +40175,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZE
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -39947,10 +40217,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZE
} while (0);
SAVE_OPLINE();
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -39969,11 +40239,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPV
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
- (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ 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_error(E_EXCEPTION | E_ERROR, "Cannot create references to/from string offsets");
-
zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var)));
HANDLE_EXCEPTION();
}
@@ -39983,11 +40252,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPV
} else {
expr_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
if (IS_CV == IS_TMP_VAR) {
- ZVAL_COPY_VALUE(&new_expr, expr_ptr);
- expr_ptr = &new_expr;
+ /* pass */
} else if (IS_CV == IS_CONST) {
- if (!Z_IMMUTABLE_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, expr_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(expr_ptr))) {
+ ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+ zval_copy_ctor_func(&new_expr);
expr_ptr = &new_expr;
}
} else if (IS_CV == IS_CV) {
@@ -40018,43 +40287,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPV
zend_ulong hval;
add_again:
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index:
- zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
- break;
- case IS_STRING:
- str = Z_STR_P(offset);
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(str, hval)) {
- goto num_index;
- }
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ str = Z_STR_P(offset);
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (ZEND_HANDLE_NUMERIC(str, hval)) {
+ goto num_index;
}
+ }
str_index:
- zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
- break;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- case IS_FALSE:
- hval = 0;
- goto num_index;
- case IS_TRUE:
- hval = 1;
- goto num_index;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto add_again;
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- zval_ptr_dtor(expr_ptr);
- /* do nothing */
- break;
+ zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index:
+ zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto add_again;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index;
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type");
+ zval_ptr_dtor(expr_ptr);
}
zval_ptr_dtor_nogc(free_op2);
} else {
@@ -40102,6 +40369,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDL
zval *container;
zval *offset;
zend_ulong hval;
+ zend_string *key;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var);
@@ -40113,72 +40381,81 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
-unset_dim_again:
- if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht;
+ do {
+ if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ HashTable *ht;
+unset_dim_array:
+ SEPARATE_ARRAY(container);
+ ht = Z_ARRVAL_P(container);
offset_again:
- SEPARATE_ARRAY(container);
- ht = Z_ARRVAL_P(container);
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- zend_hash_index_del(ht, hval);
- break;
- case IS_LONG:
- hval = Z_LVAL_P(offset);
-num_index_dim:
- zend_hash_index_del(ht, hval);
- break;
- case IS_STRING:
+ if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+ key = Z_STR_P(offset);
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
+ if (ZEND_HANDLE_NUMERIC(key, hval)) {
goto num_index_dim;
}
}
+str_index_dim:
if (ht == &EG(symbol_table)) {
- zend_delete_global_variable(Z_STR_P(offset));
+ zend_delete_global_variable(key);
} else {
- zend_hash_del(ht, Z_STR_P(offset));
+ zend_hash_del(ht, key);
}
- break;
- case IS_NULL:
- zend_hash_del(ht, STR_EMPTY_ALLOC());
- break;
- case IS_FALSE:
+ } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ hval = Z_LVAL_P(offset);
+num_index_dim:
+ zend_hash_index_del(ht, hval);
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+ offset = Z_REFVAL_P(offset);
+ goto offset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_dim;
- case IS_TRUE:
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_dim;
- case IS_RESOURCE:
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
hval = Z_RES_HANDLE_P(offset);
goto num_index_dim;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto offset_again;
- break;
- default:
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ key = STR_EMPTY_ALLOC();
+ goto str_index_dim;
+ } else {
zend_error(E_WARNING, "Illegal offset type in unset");
- break;
+ }
+ break;
+ } else if (IS_CV != IS_UNUSED && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto unset_dim_array;
+ }
}
- } else if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
- if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
- } else {
- Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
}
- } else if (IS_CV != IS_UNUSED && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto unset_dim_again;
- } else if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
- }
+ if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot use object as array");
+ } else {
+ Z_OBJ_HT_P(container)->unset_dimension(container, offset);
+ }
+ } else if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot unset string offsets");
+ }
+ } while (0);
+
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -40202,7 +40479,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error(E_EXCEPTION | E_ERROR, "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);
@@ -40251,12 +40527,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
-isset_dim_obj_again:
if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
zval *value;
zend_string *str;
+isset_dim_obj_array:
+ ht = Z_ARRVAL_P(container);
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
@@ -40271,31 +40548,31 @@ str_index_prop:
hval = Z_LVAL_P(offset);
num_index_prop:
value = zend_hash_index_find(ht, hval);
- } else {
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index_prop;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index_prop;
- case IS_FALSE:
- hval = 0;
- goto num_index_prop;
- case IS_TRUE:
- hval = 1;
- goto num_index_prop;
- case IS_RESOURCE:
- hval = Z_RES_HANDLE_P(offset);
- goto num_index_prop;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto isset_again;
- default:
- zend_error(E_WARNING, "Illegal offset type in isset or empty");
- value = NULL;
- break;
- }
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+ offset = Z_REFVAL_P(offset);
+ goto isset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ hval = Z_RES_HANDLE_P(offset);
+ goto num_index_prop;
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type in isset or empty");
+ goto isset_not_found;
}
if (opline->extended_value & ZEND_ISSET) {
@@ -40305,50 +40582,61 @@ num_index_prop:
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value));
}
- } else if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ goto isset_dim_obj_exit;
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto isset_dim_obj_array;
+ }
+ }
+
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ }
+
+ if (IS_CV == IS_UNUSED ||
+ (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
- result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
- result = 0;
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
+ goto isset_not_found;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
- zval tmp;
+ zend_long lval;
- result = 0;
- if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ lval = Z_LVAL_P(offset);
+isset_str_offset:
+ if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
+ if (opline->extended_value & ZEND_ISSET) {
+ result = 1;
+ } else {
+ result = (Z_STRVAL_P(container)[lval] == '0');
+ }
+ } else {
+ goto isset_not_found;
+ }
+ } else {
if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
- ZVAL_DUP(&tmp, offset);
- convert_to_long(&tmp);
- offset = &tmp;
- }
- }
- if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
- if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
- if ((opline->extended_value & ZEND_ISSET) ||
- Z_STRVAL_P(container)[offset->value.lval] != '0') {
- result = 1;
- }
+ lval = zval_get_long(offset);
+ goto isset_str_offset;
}
+ goto isset_not_found;
}
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
- } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto isset_dim_obj_again;
} else {
+isset_not_found:
result = ((opline->extended_value & ZEND_ISSET) == 0);
}
+isset_dim_obj_exit:
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_SMART_BRANCH(result, 1);
@@ -40376,7 +40664,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (IS_CV == IS_CONST ||
+ (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -40391,10 +40680,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV
isset_no_object:
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
- result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
}
zval_ptr_dtor_nogc(free_op2);
@@ -40409,11 +40697,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_TMPVAR_HANDLER(ZEN
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- pow_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ pow_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -40483,6 +40772,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_TMPVAR_HANDLER(ZEND_
if (str->len != 0) {
zend_write(str->val, str->len);
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(z, BP_VAR_R);
}
zend_string_release(str);
}
@@ -40766,7 +41057,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND
if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) {
break;
}
- }
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(obj, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -40834,6 +41128,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HA
ZVAL_UNDEF(&tmp_inc_filename);
if (Z_TYPE_P(inc_filename) != IS_STRING) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(inc_filename) == IS_UNDEF)) {
+ inc_filename = GET_OP1_UNDEF_CV(inc_filename, BP_VAR_R);
+ }
ZVAL_STR(&tmp_inc_filename, zval_get_string(inc_filename));
inc_filename = &tmp_inc_filename;
}
@@ -40991,6 +41288,9 @@ try_strlen:
} else {
zend_bool strict;
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+ value = GET_OP1_UNDEF_CV(value, BP_VAR_R);
+ }
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
goto try_strlen;
@@ -41157,11 +41457,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER(
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- fast_div_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ fast_div_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -41211,11 +41512,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_CONST_HANDLER(Z
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_left_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ shift_left_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -41226,11 +41528,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_TMPVAR_CONST_HANDLER(Z
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_right_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ shift_right_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -41241,12 +41544,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- concat_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
- zval_ptr_dtor_nogc(free_op1);
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+
+ do {
+ if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+ (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+ zend_string *op1_str = Z_STR_P(op1);
+ zend_string *op2_str = Z_STR_P(op2);
+ zend_string *str;
+
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+ zval_ptr_dtor_nogc(free_op1);
+ break;
+ }
+ }
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+ zval_ptr_dtor_nogc(free_op1);
+ break;
+ }
+ }
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV &&
+ !IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+ size_t len = op1_str->len;
+
+ str = zend_string_realloc(op1_str, len + op2_str->len, 0);
+ memcpy(str->val + len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ break;
+ } else {
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ }
+ } else {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ concat_function(EX_VAR(opline->result.var), op1, op2);
+ }
+ zval_ptr_dtor_nogc(free_op1);
+ } while (0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -41263,18 +41612,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HAN
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -41306,10 +41655,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HAN
} while (0);
SAVE_OPLINE();
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -41332,18 +41681,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -41375,10 +41724,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST
} while (0);
SAVE_OPLINE();
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -41496,12 +41845,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HA
{
USE_OPLINE
zend_free_op free_op1;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2;
SAVE_OPLINE();
- compare_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ compare_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -41512,11 +41861,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVAR_CONST_HANDLE
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_or_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ bitwise_or_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -41527,11 +41877,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_TMPVAR_CONST_HANDL
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_and_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ bitwise_and_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -41542,11 +41893,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMPVAR_CONST_HANDL
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_xor_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ bitwise_xor_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -41557,11 +41909,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HAN
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- boolean_xor_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -41586,6 +41939,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
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);
}
@@ -41802,7 +42158,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST
offset = EX_CONSTANT(opline->op2);
- if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+ ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -41874,7 +42231,8 @@ try_fetch_list:
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
+ } 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);
@@ -41886,10 +42244,13 @@ try_fetch_list:
} else {
ZVAL_NULL(result);
}
- } else if (Z_TYPE_P(container) == IS_REFERENCE) {
+ } 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));
}
CHECK_EXCEPTION();
@@ -41905,27 +42266,59 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_
SAVE_OPLINE();
op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
- op2 = EX_CONSTANT(opline->op2);
if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
op1_str = Z_STR_P(op1);
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ op1_str = zend_string_copy(Z_STR_P(op1));
} else {
- op1_str = zval_get_string(op1);
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ op1_str = _zval_get_string_func(op1);
}
+ op2 = EX_CONSTANT(opline->op2);
if (IS_CONST == IS_CONST) {
op2_str = Z_STR_P(op2);
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ op2_str = zend_string_copy(Z_STR_P(op2));
} else {
- op2_str = zval_get_string(op2);
- }
- str = zend_string_alloc(op1_str->len + op2_str->len, 0);
- memcpy(str->val, op1_str->val, op1_str->len);
- memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
- ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- zend_string_release(op1_str);
- }
- if (IS_CONST != IS_CONST) {
- zend_string_release(op2_str);
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ op2_str = _zval_get_string_func(op2);
}
+ do {
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ if (IS_CONST == IS_CONST) {
+ zend_string_addref(op2_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+ zend_string_release(op1_str);
+ break;
+ }
+ }
+ if (IS_CONST != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+ zend_string_addref(op1_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+ zend_string_release(op2_str);
+ break;
+ }
+ }
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ zend_string_release(op1_str);
+ }
+ if (IS_CONST != IS_CONST) {
+ zend_string_release(op2_str);
+ }
+ } while (0);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -41957,6 +42350,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
break;
}
}
+ 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();
}
@@ -41977,13 +42373,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
do {
- if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
break;
}
}
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(object, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -42030,7 +42429,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
- } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+ } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+ /* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@@ -42057,18 +42457,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -42099,10 +42499,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER
} while (0);
SAVE_OPLINE();
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -42147,6 +42547,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_CONST_HA
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;
}
@@ -42318,12 +42721,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP
offset = EX_CONSTANT(opline->op2);
-isset_dim_obj_again:
if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
zval *value;
zend_string *str;
+isset_dim_obj_array:
+ ht = Z_ARRVAL_P(container);
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
@@ -42338,31 +42742,31 @@ str_index_prop:
hval = Z_LVAL_P(offset);
num_index_prop:
value = zend_hash_index_find(ht, hval);
- } else {
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index_prop;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index_prop;
- case IS_FALSE:
- hval = 0;
- goto num_index_prop;
- case IS_TRUE:
- hval = 1;
- goto num_index_prop;
- case IS_RESOURCE:
- hval = Z_RES_HANDLE_P(offset);
- goto num_index_prop;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto isset_again;
- default:
- zend_error(E_WARNING, "Illegal offset type in isset or empty");
- value = NULL;
- break;
- }
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+ offset = Z_REFVAL_P(offset);
+ goto isset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ hval = Z_RES_HANDLE_P(offset);
+ goto num_index_prop;
+ } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type in isset or empty");
+ goto isset_not_found;
}
if (opline->extended_value & ZEND_ISSET) {
@@ -42372,50 +42776,62 @@ num_index_prop:
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value));
}
- } else if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ goto isset_dim_obj_exit;
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto isset_dim_obj_array;
+ }
+ }
+
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ }
+
+ if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED ||
+ ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
- result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
- result = 0;
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
+ goto isset_not_found;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
- zval tmp;
+ zend_long lval;
- result = 0;
- if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ lval = Z_LVAL_P(offset);
+isset_str_offset:
+ if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
+ if (opline->extended_value & ZEND_ISSET) {
+ result = 1;
+ } else {
+ result = (Z_STRVAL_P(container)[lval] == '0');
+ }
+ } else {
+ goto isset_not_found;
+ }
+ } else {
if (IS_CONST & (IS_CV|IS_VAR)) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
- ZVAL_DUP(&tmp, offset);
- convert_to_long(&tmp);
- offset = &tmp;
+ lval = zval_get_long(offset);
+ goto isset_str_offset;
}
+ goto isset_not_found;
}
- if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
- if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
- if ((opline->extended_value & ZEND_ISSET) ||
- Z_STRVAL_P(container)[offset->value.lval] != '0') {
- result = 1;
- }
- }
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
- } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto isset_dim_obj_again;
} else {
+isset_not_found:
result = ((opline->extended_value & ZEND_ISSET) == 0);
}
+isset_dim_obj_exit:
+
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_SMART_BRANCH(result, 1);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
@@ -42442,7 +42858,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM
offset = EX_CONSTANT(opline->op2);
- if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+ ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -42457,10 +42874,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM
isset_no_object:
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
- result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
}
zval_ptr_dtor_nogc(free_op1);
@@ -42505,6 +42921,9 @@ try_instanceof:
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);
@@ -42518,11 +42937,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_TMPVAR_CONST_HANDLER(
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- pow_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ pow_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -42547,6 +42967,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
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);
}
@@ -42748,6 +43171,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_VAR_HAND
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;
}
@@ -42934,6 +43360,9 @@ try_instanceof:
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);
@@ -42961,6 +43390,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
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);
}
@@ -43162,6 +43594,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_H
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;
}
@@ -43452,11 +43887,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_TMPVAR_CV_HANDLER(ZEN
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- fast_div_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ fast_div_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -43506,11 +43942,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_CV_HANDLER(ZEND
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_left_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ shift_left_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -43521,11 +43958,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_TMPVAR_CV_HANDLER(ZEND
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_right_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ shift_right_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -43536,12 +43974,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- concat_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
- zval_ptr_dtor_nogc(free_op1);
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+
+ do {
+ if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+ (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+ zend_string *op1_str = Z_STR_P(op1);
+ zend_string *op2_str = Z_STR_P(op2);
+ zend_string *str;
+
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+ zval_ptr_dtor_nogc(free_op1);
+ break;
+ }
+ }
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+ zval_ptr_dtor_nogc(free_op1);
+ break;
+ }
+ }
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV &&
+ !IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+ size_t len = op1_str->len;
+
+ str = zend_string_realloc(op1_str, len + op2_str->len, 0);
+ memcpy(str->val + len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ break;
+ } else {
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ }
+ } else {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ concat_function(EX_VAR(opline->result.var), op1, op2);
+ }
+ zval_ptr_dtor_nogc(free_op1);
+ } while (0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -43558,18 +44042,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CV_HANDLE
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -43601,10 +44085,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CV_HANDLE
} while (0);
SAVE_OPLINE();
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -43627,18 +44111,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CV_HA
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -43670,10 +44154,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CV_HA
} while (0);
SAVE_OPLINE();
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -43791,12 +44275,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDL
{
USE_OPLINE
zend_free_op free_op1;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2;
SAVE_OPLINE();
- compare_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ compare_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -43807,11 +44291,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVAR_CV_HANDLER(Z
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_or_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ bitwise_or_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -43822,11 +44307,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_TMPVAR_CV_HANDLER(
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_and_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ bitwise_and_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -43837,11 +44323,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMPVAR_CV_HANDLER(
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_xor_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ bitwise_xor_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -43852,11 +44339,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_CV_HANDLE
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- boolean_xor_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -43912,7 +44400,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HA
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+ ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -43974,27 +44463,59 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN
SAVE_OPLINE();
op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
- op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
op1_str = Z_STR_P(op1);
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ op1_str = zend_string_copy(Z_STR_P(op1));
} else {
- op1_str = zval_get_string(op1);
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ op1_str = _zval_get_string_func(op1);
}
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
if (IS_CV == IS_CONST) {
op2_str = Z_STR_P(op2);
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ op2_str = zend_string_copy(Z_STR_P(op2));
} else {
- op2_str = zval_get_string(op2);
- }
- str = zend_string_alloc(op1_str->len + op2_str->len, 0);
- memcpy(str->val, op1_str->val, op1_str->len);
- memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
- ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- zend_string_release(op1_str);
- }
- if (IS_CV != IS_CONST) {
- zend_string_release(op2_str);
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ op2_str = _zval_get_string_func(op2);
}
+ do {
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ if (IS_CV == IS_CONST) {
+ zend_string_addref(op2_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+ zend_string_release(op1_str);
+ break;
+ }
+ }
+ if (IS_CV != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+ zend_string_addref(op1_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+ zend_string_release(op2_str);
+ break;
+ }
+ }
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ zend_string_release(op1_str);
+ }
+ if (IS_CV != IS_CONST) {
+ zend_string_release(op2_str);
+ }
+ } while (0);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -44015,7 +44536,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
SAVE_OPLINE();
- function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ function_name = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
@@ -44026,6 +44547,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
break;
}
}
+ 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();
}
@@ -44046,13 +44570,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
do {
- if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
break;
}
}
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(object, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -44099,7 +44626,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
- } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+ } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+ /* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@@ -44126,18 +44654,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZE
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -44168,10 +44696,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZE
} while (0);
SAVE_OPLINE();
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -44200,14 +44728,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP
HANDLE_EXCEPTION();
}
- offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
-isset_dim_obj_again:
if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
zval *value;
zend_string *str;
+isset_dim_obj_array:
+ ht = Z_ARRVAL_P(container);
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
@@ -44222,31 +44751,31 @@ str_index_prop:
hval = Z_LVAL_P(offset);
num_index_prop:
value = zend_hash_index_find(ht, hval);
- } else {
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index_prop;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index_prop;
- case IS_FALSE:
- hval = 0;
- goto num_index_prop;
- case IS_TRUE:
- hval = 1;
- goto num_index_prop;
- case IS_RESOURCE:
- hval = Z_RES_HANDLE_P(offset);
- goto num_index_prop;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto isset_again;
- default:
- zend_error(E_WARNING, "Illegal offset type in isset or empty");
- value = NULL;
- break;
- }
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+ offset = Z_REFVAL_P(offset);
+ goto isset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ hval = Z_RES_HANDLE_P(offset);
+ goto num_index_prop;
+ } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type in isset or empty");
+ goto isset_not_found;
}
if (opline->extended_value & ZEND_ISSET) {
@@ -44256,50 +44785,62 @@ num_index_prop:
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value));
}
- } else if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ goto isset_dim_obj_exit;
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto isset_dim_obj_array;
+ }
+ }
+
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ }
+
+ if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED ||
+ ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
- result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
- result = 0;
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
+ goto isset_not_found;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
- zval tmp;
+ zend_long lval;
- result = 0;
- if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ lval = Z_LVAL_P(offset);
+isset_str_offset:
+ if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
+ if (opline->extended_value & ZEND_ISSET) {
+ result = 1;
+ } else {
+ result = (Z_STRVAL_P(container)[lval] == '0');
+ }
+ } else {
+ goto isset_not_found;
+ }
+ } else {
if (IS_CV & (IS_CV|IS_VAR)) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
- ZVAL_DUP(&tmp, offset);
- convert_to_long(&tmp);
- offset = &tmp;
- }
- }
- if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
- if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
- if ((opline->extended_value & ZEND_ISSET) ||
- Z_STRVAL_P(container)[offset->value.lval] != '0') {
- result = 1;
- }
+ lval = zval_get_long(offset);
+ goto isset_str_offset;
}
+ goto isset_not_found;
}
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
- } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto isset_dim_obj_again;
} else {
+isset_not_found:
result = ((opline->extended_value & ZEND_ISSET) == 0);
}
+isset_dim_obj_exit:
+
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_SMART_BRANCH(result, 1);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
@@ -44326,7 +44867,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+ ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -44341,10 +44883,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM
isset_no_object:
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
- result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
}
zval_ptr_dtor_nogc(free_op1);
@@ -44358,11 +44899,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_TMPVAR_CV_HANDLER(ZEN
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2;
SAVE_OPLINE();
- pow_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ pow_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -44508,11 +45050,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- fast_div_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ fast_div_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -44562,11 +45105,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER(
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_left_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ shift_left_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -44577,11 +45121,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_TMPVAR_TMPVAR_HANDLER(
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- shift_right_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ shift_right_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -44592,12 +45137,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- concat_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
- zval_ptr_dtor_nogc(free_op1);
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+
+ do {
+ if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+ ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+ zend_string *op1_str = Z_STR_P(op1);
+ zend_string *op2_str = Z_STR_P(op2);
+ zend_string *str;
+
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+ zval_ptr_dtor_nogc(free_op1);
+ break;
+ }
+ }
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+ zval_ptr_dtor_nogc(free_op1);
+ break;
+ }
+ }
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV &&
+ !IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+ size_t len = op1_str->len;
+
+ str = zend_string_realloc(op1_str, len + op2_str->len, 0);
+ memcpy(str->val + len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ break;
+ } else {
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ }
+ } else {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ concat_function(EX_VAR(opline->result.var), op1, op2);
+ }
+ zval_ptr_dtor_nogc(free_op1);
+ } while (0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -44614,18 +45205,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HA
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -44657,10 +45248,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HA
} while (0);
SAVE_OPLINE();
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -44683,18 +45274,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVA
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -44726,10 +45317,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVA
} while (0);
SAVE_OPLINE();
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -44847,12 +45438,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_H
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2;
SAVE_OPLINE();
- compare_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ compare_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -44863,11 +45454,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_HANDL
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_or_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ bitwise_or_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -44878,11 +45470,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_TMPVAR_TMPVAR_HAND
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_and_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ bitwise_and_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -44893,11 +45486,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR_HAND
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_xor_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ bitwise_xor_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -44908,11 +45502,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HA
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- boolean_xor_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -44968,7 +45563,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVA
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+ ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -45031,27 +45627,59 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR
SAVE_OPLINE();
op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
- op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
op1_str = Z_STR_P(op1);
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ op1_str = zend_string_copy(Z_STR_P(op1));
} else {
- op1_str = zval_get_string(op1);
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ op1_str = _zval_get_string_func(op1);
}
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
op2_str = Z_STR_P(op2);
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ op2_str = zend_string_copy(Z_STR_P(op2));
} else {
- op2_str = zval_get_string(op2);
- }
- str = zend_string_alloc(op1_str->len + op2_str->len, 0);
- memcpy(str->val, op1_str->val, op1_str->len);
- memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
- ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- zend_string_release(op1_str);
- }
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
- zend_string_release(op2_str);
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ op2_str = _zval_get_string_func(op2);
}
+ do {
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (UNEXPECTED(op1_str->len == 0)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+ zend_string_addref(op2_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+ zend_string_release(op1_str);
+ break;
+ }
+ }
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ if (UNEXPECTED(op2_str->len == 0)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+ zend_string_addref(op1_str);
+ }
+ ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+ zend_string_release(op2_str);
+ break;
+ }
+ }
+ str = zend_string_alloc(op1_str->len + op2_str->len, 0);
+ memcpy(str->val, op1_str->val, op1_str->len);
+ memcpy(str->val + op1_str->len, op2_str->val, op2_str->len+1);
+ ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ zend_string_release(op1_str);
+ }
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+ zend_string_release(op2_str);
+ }
+ } while (0);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -45083,6 +45711,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T
break;
}
}
+ 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();
}
@@ -45103,13 +45734,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T
if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
do {
- if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
break;
}
}
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ GET_OP1_UNDEF_CV(object, BP_VAR_R);
+ }
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -45156,7 +45790,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
- } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+ } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+ /* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@@ -45184,18 +45819,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLE
do {
int result;
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
} else {
break;
}
- } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
} else {
break;
@@ -45226,10 +45861,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLE
} while (0);
SAVE_OPLINE();
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
result = EX_VAR(opline->result.var);
@@ -45260,12 +45895,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
-isset_dim_obj_again:
if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
zval *value;
zend_string *str;
+isset_dim_obj_array:
+ ht = Z_ARRVAL_P(container);
isset_again:
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
@@ -45280,31 +45916,31 @@ str_index_prop:
hval = Z_LVAL_P(offset);
num_index_prop:
value = zend_hash_index_find(ht, hval);
- } else {
- switch (Z_TYPE_P(offset)) {
- case IS_DOUBLE:
- hval = zend_dval_to_lval(Z_DVAL_P(offset));
- goto num_index_prop;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index_prop;
- case IS_FALSE:
- hval = 0;
- goto num_index_prop;
- case IS_TRUE:
- hval = 1;
- goto num_index_prop;
- case IS_RESOURCE:
- hval = Z_RES_HANDLE_P(offset);
- goto num_index_prop;
- case IS_REFERENCE:
- offset = Z_REFVAL_P(offset);
- goto isset_again;
- default:
- zend_error(E_WARNING, "Illegal offset type in isset or empty");
- value = NULL;
- break;
- }
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+ offset = Z_REFVAL_P(offset);
+ goto isset_again;
+ } else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+ hval = zend_dval_to_lval(Z_DVAL_P(offset));
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_NULL) {
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_FALSE) {
+ hval = 0;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_TRUE) {
+ hval = 1;
+ goto num_index_prop;
+ } else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+ hval = Z_RES_HANDLE_P(offset);
+ goto num_index_prop;
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+ GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ str = STR_EMPTY_ALLOC();
+ goto str_index_prop;
+ } else {
+ zend_error(E_WARNING, "Illegal offset type in isset or empty");
+ goto isset_not_found;
}
if (opline->extended_value & ZEND_ISSET) {
@@ -45314,50 +45950,61 @@ num_index_prop:
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value));
}
- } else if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ goto isset_dim_obj_exit;
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto isset_dim_obj_array;
+ }
+ }
+
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+ offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
+ }
+
+ if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED ||
+ ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) {
if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) {
- result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
- result = 0;
- }
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
+ goto isset_not_found;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
- zval tmp;
+ zend_long lval;
- result = 0;
- if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+ lval = Z_LVAL_P(offset);
+isset_str_offset:
+ if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) {
+ if (opline->extended_value & ZEND_ISSET) {
+ result = 1;
+ } else {
+ result = (Z_STRVAL_P(container)[lval] == '0');
+ }
+ } else {
+ goto isset_not_found;
+ }
+ } else {
if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) {
ZVAL_DEREF(offset);
}
if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */
|| (Z_TYPE_P(offset) == IS_STRING /* or numeric string */
&& IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) {
- ZVAL_DUP(&tmp, offset);
- convert_to_long(&tmp);
- offset = &tmp;
- }
- }
- if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
- if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
- if ((opline->extended_value & ZEND_ISSET) ||
- Z_STRVAL_P(container)[offset->value.lval] != '0') {
- result = 1;
- }
+ lval = zval_get_long(offset);
+ goto isset_str_offset;
}
+ goto isset_not_found;
}
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
- } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- goto isset_dim_obj_again;
} else {
+isset_not_found:
result = ((opline->extended_value & ZEND_ISSET) == 0);
}
+isset_dim_obj_exit:
zval_ptr_dtor_nogc(free_op2);
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_SMART_BRANCH(result, 1);
@@ -45385,7 +46032,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
- if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+ ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -45400,10 +46048,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM
isset_no_object:
result = ((opline->extended_value & ZEND_ISSET) == 0);
} else {
- result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- if ((opline->extended_value & ZEND_ISSET) == 0) {
- result = !result;
- }
+ result =
+ ((opline->extended_value & ZEND_ISSET) == 0) ^
+ Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
}
zval_ptr_dtor_nogc(free_op2);
@@ -45418,11 +46065,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
SAVE_OPLINE();
- pow_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ pow_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -46689,52 +47337,52 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_BRK_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_BRK_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_BRK_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_BRK_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_BRK_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_CONT_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_CONT_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_CONT_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_CONT_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_CONT_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,
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index 7d49bea509..0b8caadc74 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -259,6 +259,26 @@ $op2_get_obj_zval_ptr = array(
"TMPVAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)",
);
+$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)",
+);
+
+$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)",
+);
+
$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)",
@@ -449,6 +469,7 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
$op1_get_zval_ptr_ptr, $op2_get_zval_ptr_ptr,
$op1_get_zval_ptr_ptr_undef, $op2_get_zval_ptr_ptr_undef,
$op1_get_obj_zval_ptr, $op2_get_obj_zval_ptr,
+ $op1_get_obj_zval_ptr_undef, $op2_get_obj_zval_ptr_undef,
$op1_get_obj_zval_ptr_deref, $op2_get_obj_zval_ptr_deref,
$op1_get_obj_zval_ptr_ptr, $op2_get_obj_zval_ptr_ptr,
$op1_get_obj_zval_ptr_ptr_undef, $op2_get_obj_zval_ptr_ptr_undef,
@@ -475,6 +496,8 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
"/GET_OP2_ZVAL_PTR_PTR_UNDEF\(([^)]*)\)/",
"/GET_OP1_OBJ_ZVAL_PTR\(([^)]*)\)/",
"/GET_OP2_OBJ_ZVAL_PTR\(([^)]*)\)/",
+ "/GET_OP1_OBJ_ZVAL_PTR_UNDEF\(([^)]*)\)/",
+ "/GET_OP2_OBJ_ZVAL_PTR_UNDEF\(([^)]*)\)/",
"/GET_OP1_OBJ_ZVAL_PTR_DEREF\(([^)]*)\)/",
"/GET_OP2_OBJ_ZVAL_PTR_DEREF\(([^)]*)\)/",
"/GET_OP1_OBJ_ZVAL_PTR_PTR\(([^)]*)\)/",
@@ -517,6 +540,8 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
$op2_get_zval_ptr_ptr_undef[$op2],
$op1_get_obj_zval_ptr[$op1],
$op2_get_obj_zval_ptr[$op2],
+ $op1_get_obj_zval_ptr_undef[$op1],
+ $op2_get_obj_zval_ptr_undef[$op2],
$op1_get_obj_zval_ptr_deref[$op1],
$op2_get_obj_zval_ptr_deref[$op2],
$op1_get_obj_zval_ptr_ptr[$op1],
diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c
index 95b8b859eb..705ab9cd29 100644
--- a/Zend/zend_vm_opcodes.c
+++ b/Zend/zend_vm_opcodes.c
@@ -72,8 +72,8 @@ const char *zend_vm_opcodes_map[173] = {
"ZEND_JMPNZ_EX",
"ZEND_CASE",
NULL,
- "ZEND_BRK",
- "ZEND_CONT",
+ NULL,
+ NULL,
"ZEND_BOOL",
"ZEND_FAST_CONCAT",
"ZEND_ROPE_INIT",
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index 89a0d3139b..f6de5b1b57 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -82,8 +82,6 @@ END_EXTERN_C()
#define ZEND_JMPZ_EX 46
#define ZEND_JMPNZ_EX 47
#define ZEND_CASE 48
-#define ZEND_BRK 50
-#define ZEND_CONT 51
#define ZEND_BOOL 52
#define ZEND_FAST_CONCAT 53
#define ZEND_ROPE_INIT 54