diff --git a/Zend/Makefile.am b/Zend/Makefile.am
index 5ec4590fefe19..e5757fac56d04 100644
--- a/Zend/Makefile.am
+++ b/Zend/Makefile.am
@@ -17,7 +17,8 @@ libZend_la_SOURCES=\
 	zend_objects_API.c zend_ts_hash.c zend_stream.c \
 	zend_default_classes.c \
 	zend_iterators.c zend_interfaces.c zend_exceptions.c \
-	zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c
+	zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c \
+	zend_generators.c
 
 libZend_la_LDFLAGS =
 libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
diff --git a/Zend/Zend.dsp b/Zend/Zend.dsp
index ebe01978c4e1e..23ebd4532b5e7 100644
--- a/Zend/Zend.dsp
+++ b/Zend/Zend.dsp
@@ -159,6 +159,10 @@ SOURCE=.\zend_float.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\zend_generators.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\zend_hash.c
 # End Source File
 # Begin Source File
diff --git a/Zend/ZendTS.dsp b/Zend/ZendTS.dsp
index 3494cd4e17ff8..3be2c58bed6fa 100644
--- a/Zend/ZendTS.dsp
+++ b/Zend/ZendTS.dsp
@@ -185,6 +185,10 @@ SOURCE=.\zend_extensions.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\zend_generators.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\zend_hash.c
 # End Source File
 # Begin Source File
diff --git a/Zend/tests/errmsg_043.phpt b/Zend/tests/errmsg_043.phpt
deleted file mode 100644
index 3de8bc2062e9c..0000000000000
--- a/Zend/tests/errmsg_043.phpt
+++ /dev/null
@@ -1,12 +0,0 @@
---TEST--
-errmsg: cannot create references to temp array
---FILE--
-<?php
-
-foreach (array(1,2,3) as $k=>&$v) {
-}
-
-echo "Done\n";
-?>
---EXPECTF--	
-Fatal error: Cannot create references to elements of a temporary array expression in %s on line %d
diff --git a/Zend/tests/foreach_temp_array_expr_with_refs.phpt b/Zend/tests/foreach_temp_array_expr_with_refs.phpt
new file mode 100644
index 0000000000000..8978b7b011419
--- /dev/null
+++ b/Zend/tests/foreach_temp_array_expr_with_refs.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Temporary array expressions can be iterated by reference
+--FILE--
+<?php
+
+$a = 'a';
+$b = 'b';
+
+foreach ([&$a, &$b] as &$value) {
+    $value .= '-foo';
+}
+
+var_dump($a, $b);
+
+?>
+--EXPECT--
+string(5) "a-foo"
+string(5) "b-foo"
diff --git a/Zend/tests/generators/auto_incrementing_keys.phpt b/Zend/tests/generators/auto_incrementing_keys.phpt
new file mode 100644
index 0000000000000..acfb2f2ce00bb
--- /dev/null
+++ b/Zend/tests/generators/auto_incrementing_keys.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Generator keys are auto-incrementing by default
+--FILE--
+<?php
+
+function gen() {
+    yield 'foo';
+    yield 'bar';
+    yield 5 => 'rab';
+    yield 'oof';
+}
+
+foreach (gen() as $k => $v) {
+    echo $k, ' => ', $v, "\n";
+}
+
+?>
+--EXPECT--
+0 => foo
+1 => bar
+5 => rab
+6 => oof
diff --git a/Zend/tests/generators/backtrace.phpt b/Zend/tests/generators/backtrace.phpt
new file mode 100644
index 0000000000000..5fed1d467e676
--- /dev/null
+++ b/Zend/tests/generators/backtrace.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Printing the stack trace in a generator
+--FILE--
+<?php
+
+function f1() {
+    debug_print_backtrace();
+}
+
+function f2($arg1, $arg2) {
+    f1();
+    yield; // force generator
+}
+
+function f3($gen) {
+    $gen->rewind(); // trigger run
+}
+
+$gen = f2('foo', 'bar');
+f3($gen);
+
+?>
+--EXPECTF--
+#0  f1() called at [%s:%d]
+#1  f2(foo, bar)
+#2  Generator->rewind() called at [%s:%d]
+#3  f3(Generator Object ()) called at [%s:%d]
diff --git a/Zend/tests/generators/clone.phpt b/Zend/tests/generators/clone.phpt
new file mode 100644
index 0000000000000..36811dfe6e744
--- /dev/null
+++ b/Zend/tests/generators/clone.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Generators can be cloned
+--FILE--
+<?php
+
+function firstN($end) {
+    for ($i = 0; $i < $end; ++$i) {
+        yield $i;
+    }
+}
+
+$g1 = firstN(5);
+var_dump($g1->current());
+$g1->next();
+
+$g2 = clone $g1;
+var_dump($g2->current());
+$g2->next();
+
+var_dump($g2->current());
+var_dump($g1->current());
+
+$g1->next();
+var_dump($g1->current());
+
+?>
+--EXPECT--
+int(0)
+int(1)
+int(2)
+int(1)
+int(2)
diff --git a/Zend/tests/generators/clone_with_foreach.phpt b/Zend/tests/generators/clone_with_foreach.phpt
new file mode 100644
index 0000000000000..b05ed073120dc
--- /dev/null
+++ b/Zend/tests/generators/clone_with_foreach.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Cloning a generator with a foreach loop properly adds a ref for the loop var
+--FILE--
+<?php
+
+function gen() {
+    foreach ([1, 2, 3] as $i) {
+        yield $i;
+    }
+}
+
+$g1 = gen();
+var_dump($g1->current());
+
+$g2 = clone $g1;
+var_dump($g2->current());
+
+$g1->next();
+$g2->next();
+var_dump($g1->current());
+var_dump($g2->current());
+
+unset($g1);
+$g2->next();
+var_dump($g2->current());
+
+?>
+--EXPECT--
+int(1)
+int(1)
+int(2)
+int(2)
+int(3)
diff --git a/Zend/tests/generators/clone_with_stack.phpt b/Zend/tests/generators/clone_with_stack.phpt
new file mode 100644
index 0000000000000..5a8e6d842ca8e
--- /dev/null
+++ b/Zend/tests/generators/clone_with_stack.phpt
@@ -0,0 +1,18 @@
+--TEST--
+A generator with an active stack can be cloned
+--FILE--
+<?php
+
+function gen() {
+    var_dump(str_repeat("x", yield));
+}
+
+$g1 = gen();
+$g1->rewind();
+$g2 = clone $g1;
+unset($g1);
+$g2->send(10);
+
+?>
+--EXPECT--
+string(10) "xxxxxxxxxx"
diff --git a/Zend/tests/generators/clone_with_symbol_table.phpt b/Zend/tests/generators/clone_with_symbol_table.phpt
new file mode 100644
index 0000000000000..e1fefebd8fa42
--- /dev/null
+++ b/Zend/tests/generators/clone_with_symbol_table.phpt
@@ -0,0 +1,27 @@
+--TEST--
+A generator using a symbol table can be cloned
+--FILE--
+<?php
+
+function gen() {
+    // force compiled variable for $foo
+    $foo = 'foo';
+
+    // force symbol table
+    extract(['foo' => 'bar']);
+
+    // interrupt
+    yield;
+
+    var_dump($foo);
+}
+
+$g1 = gen();
+$g1->rewind();
+$g2 = clone $g1;
+unset($g1);
+$g2->next();
+
+?>
+--EXPECT--
+string(3) "bar"
diff --git a/Zend/tests/generators/clone_with_this.phpt b/Zend/tests/generators/clone_with_this.phpt
new file mode 100644
index 0000000000000..b242d851ebec5
--- /dev/null
+++ b/Zend/tests/generators/clone_with_this.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Cloning a generator method (with $this)
+--FILE--
+<?php
+
+class Test {
+    protected $foo;
+
+    public function gen() {
+        $this->foo = 'bar';
+        yield; // interrupt
+        var_dump($this->foo);
+    }
+}
+
+$g1 = (new Test)->gen();
+$g1->rewind(); // goto yield
+$g2 = clone $g1;
+unset($g1);
+$g2->next();
+
+?>
+--EXPECT--
+string(3) "bar"
diff --git a/Zend/tests/generators/dynamic_call.phpt b/Zend/tests/generators/dynamic_call.phpt
new file mode 100644
index 0000000000000..d56454095294d
--- /dev/null
+++ b/Zend/tests/generators/dynamic_call.phpt
@@ -0,0 +1,19 @@
+--TEST--
+It's possible to invoke a generator dynamically
+--FILE--
+<?php
+
+function gen($foo, $bar) {
+    yield $foo;
+    yield $bar;
+}
+
+$gen = call_user_func('gen', 'bar', 'foo');
+foreach ($gen as $value) {
+    var_dump($value);
+}
+
+?>
+--EXPECT--
+string(3) "bar"
+string(3) "foo"
diff --git a/Zend/tests/generators/errors/generator_cannot_return_before_yield_error.phpt b/Zend/tests/generators/errors/generator_cannot_return_before_yield_error.phpt
new file mode 100644
index 0000000000000..ad618d20ba2d4
--- /dev/null
+++ b/Zend/tests/generators/errors/generator_cannot_return_before_yield_error.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Generators cannot return values (even before yield)
+--FILE--
+<?php
+
+function gen() {
+    return $foo;
+    yield;
+}
+
+?>
+--EXPECTF--
+Fatal error: Generators cannot return values using "return" in %s on line 4
diff --git a/Zend/tests/generators/errors/generator_cannot_return_error.phpt b/Zend/tests/generators/errors/generator_cannot_return_error.phpt
new file mode 100644
index 0000000000000..51149062a7ed6
--- /dev/null
+++ b/Zend/tests/generators/errors/generator_cannot_return_error.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Generators cannot return values
+--FILE--
+<?php
+
+function gen() {
+    yield;
+	return $abc;
+}
+
+?>
+--EXPECTF--
+Fatal error: Generators cannot return values using "return" in %s on line 5
diff --git a/Zend/tests/generators/errors/generator_extend_error.phpt b/Zend/tests/generators/errors/generator_extend_error.phpt
new file mode 100644
index 0000000000000..550f16ae03b9d
--- /dev/null
+++ b/Zend/tests/generators/errors/generator_extend_error.phpt
@@ -0,0 +1,10 @@
+--TEST--
+The Generator class cannot be extended
+--FILE--
+<?php
+
+class ExtendedGenerator extends Generator { }
+
+?>
+--EXPECTF--
+Fatal error: Class ExtendedGenerator may not inherit from final class (Generator) in %s on line %d
diff --git a/Zend/tests/generators/errors/generator_instantiate_error.phpt b/Zend/tests/generators/errors/generator_instantiate_error.phpt
new file mode 100644
index 0000000000000..f8941c087af42
--- /dev/null
+++ b/Zend/tests/generators/errors/generator_instantiate_error.phpt
@@ -0,0 +1,10 @@
+--TEST--
+It's not possible to directly instantiate the Generator class
+--FILE--
+<?php
+
+new Generator;
+
+?>
+--EXPECTF--
+Catchable fatal error: The "Generator" class is reserved for internal use and cannot be manually instantiated in %s on line %d
diff --git a/Zend/tests/generators/errors/non_ref_generator_iterated_by_ref_error.phpt b/Zend/tests/generators/errors/non_ref_generator_iterated_by_ref_error.phpt
new file mode 100644
index 0000000000000..de5b22f6ba63e
--- /dev/null
+++ b/Zend/tests/generators/errors/non_ref_generator_iterated_by_ref_error.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Non-ref generators cannot be iterated by-ref
+--FILE--
+<?php
+
+function gen() { yield; }
+
+$gen = gen();
+foreach ($gen as &$value) { }
+
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'Exception' with message 'You can only iterate a generator by-reference if it declared that it yields by-reference' in %s:%d
+Stack trace:
+#0 %s(%d): unknown()
+#1 {main}
+  thrown in %s on line %d
+
diff --git a/Zend/tests/generators/errors/resume_running_generator_error.phpt b/Zend/tests/generators/errors/resume_running_generator_error.phpt
new file mode 100644
index 0000000000000..567d72f3f9483
--- /dev/null
+++ b/Zend/tests/generators/errors/resume_running_generator_error.phpt
@@ -0,0 +1,17 @@
+--TEST--
+It is not possible to resume an already running generator
+--FILE--
+<?php
+
+function gen() {
+    $gen = yield;
+    $gen->next();
+}
+
+$gen = gen();
+$gen->send($gen);
+$gen->next();
+
+?>
+--EXPECTF--
+Fatal error: Cannot resume an already running generator in %s on line %d
diff --git a/Zend/tests/generators/errors/serialize_unserialize_error.phpt b/Zend/tests/generators/errors/serialize_unserialize_error.phpt
new file mode 100644
index 0000000000000..a8470b0a63ab8
--- /dev/null
+++ b/Zend/tests/generators/errors/serialize_unserialize_error.phpt
@@ -0,0 +1,46 @@
+--TEST--
+Generators can't be serialized or unserialized
+--FILE--
+<?php
+
+function gen() { yield; }
+
+$gen = gen();
+
+try {
+    serialize($gen);
+} catch (Exception $e) {
+    echo $e, "\n\n";
+}
+
+try {
+    var_dump(unserialize('O:9:"Generator":0:{}'));
+} catch (Exception $e) {
+    echo $e, "\n\n";
+}
+
+try {
+    var_dump(unserialize('C:9:"Generator":0:{}'));
+} catch (Exception $e) {
+    echo $e;
+}
+
+?>
+--EXPECTF--
+exception 'Exception' with message 'Serialization of 'Generator' is not allowed' in %s:%d
+Stack trace:
+#0 %s(%d): serialize(Object(Generator))
+#1 {main}
+
+exception 'Exception' with message 'Unserialization of 'Generator' is not allowed' in %s:%d
+Stack trace:
+#0 [internal function]: Generator->__wakeup()
+#1 %s(%d): unserialize('O:9:"Generator"...')
+#2 {main}
+
+
+Notice: unserialize(): Error at offset 19 of 20 bytes in %s on line %d
+exception 'Exception' with message 'Unserialization of 'Generator' is not allowed' in %s:%d
+Stack trace:
+#0 %s(%d): unserialize('C:9:"Generator"...')
+#1 {main}
diff --git a/Zend/tests/generators/errors/yield_const_by_ref_error.phpt b/Zend/tests/generators/errors/yield_const_by_ref_error.phpt
new file mode 100644
index 0000000000000..e79f83e24a192
--- /dev/null
+++ b/Zend/tests/generators/errors/yield_const_by_ref_error.phpt
@@ -0,0 +1,16 @@
+--TEST--
+A notice is thrown when yielding a constant value by reference
+--FILE--
+<?php
+
+function &gen() {
+    yield "foo";
+}
+
+$gen = gen();
+var_dump($gen->current());
+
+?>
+--EXPECTF--
+Notice: Only variable references should be yielded by reference in %s on line %d
+string(3) "foo"
diff --git a/Zend/tests/generators/errors/yield_in_force_closed_finally_error.phpt b/Zend/tests/generators/errors/yield_in_force_closed_finally_error.phpt
new file mode 100644
index 0000000000000..aada676a68e8e
--- /dev/null
+++ b/Zend/tests/generators/errors/yield_in_force_closed_finally_error.phpt
@@ -0,0 +1,29 @@
+--TEST--
+yield cannot be used in a finally block when the generator is force-closed
+--FILE--
+<?php
+
+function gen() {
+    try {
+        echo "before yield\n";
+        yield;
+        echo "after yield\n";
+    } finally {
+        echo "before yield in finally\n";
+        yield;
+        echo "after yield in finally\n";
+    }
+
+    echo "after finally\n";
+}
+
+$gen = gen();
+$gen->rewind();
+unset($gen);
+
+?>
+--EXPECTF--
+before yield
+before yield in finally
+
+Fatal error: Cannot yield from finally in a force-closed generator in %s on line %d
diff --git a/Zend/tests/generators/errors/yield_non_ref_function_call_by_ref_error.phpt b/Zend/tests/generators/errors/yield_non_ref_function_call_by_ref_error.phpt
new file mode 100644
index 0000000000000..4b8563331c673
--- /dev/null
+++ b/Zend/tests/generators/errors/yield_non_ref_function_call_by_ref_error.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Yielding the result of a non-ref function call throw a notice
+--FILE--
+<?php
+
+function foo() {
+    return "bar";
+}
+
+function &gen() {
+    yield foo();
+}
+
+$gen = gen();
+var_dump($gen->current());
+
+?>
+--EXPECTF--
+Notice: Only variable references should be yielded by reference in %s on line %d
+string(3) "bar"
diff --git a/Zend/tests/generators/errors/yield_outside_function_error.phpt b/Zend/tests/generators/errors/yield_outside_function_error.phpt
new file mode 100644
index 0000000000000..f999c1c03bf48
--- /dev/null
+++ b/Zend/tests/generators/errors/yield_outside_function_error.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Yield cannot be used outside of functions
+--FILE--
+<?php
+
+yield "Test";
+
+?>
+--EXPECTF--
+Fatal error: The "yield" expression can only be used inside a function in %s on line %d
diff --git a/Zend/tests/generators/fibonacci.phpt b/Zend/tests/generators/fibonacci.phpt
new file mode 100644
index 0000000000000..35b31352ff3e7
--- /dev/null
+++ b/Zend/tests/generators/fibonacci.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Creating an infinite fibonacci list using a generator
+--FILE--
+<?php
+
+function fib() {
+    list($a, $b) = [1, 1];
+    while (true) {
+        yield $b;
+        list($a, $b) = [$b, $a + $b];
+    }
+}
+
+foreach (fib() as $n) {
+    if ($n > 1000) break;
+
+    var_dump($n);
+}
+
+?>
+--EXPECT--
+int(1)
+int(2)
+int(3)
+int(5)
+int(8)
+int(13)
+int(21)
+int(34)
+int(55)
+int(89)
+int(144)
+int(233)
+int(377)
+int(610)
+int(987)
diff --git a/Zend/tests/generators/finally_ran_on_close.phpt b/Zend/tests/generators/finally_ran_on_close.phpt
new file mode 100644
index 0000000000000..44a84fae5c799
--- /dev/null
+++ b/Zend/tests/generators/finally_ran_on_close.phpt
@@ -0,0 +1,25 @@
+--TEST--
+finally is run even if a generator is closed mid-execution
+--FILE--
+<?php
+
+function gen() {
+    try {
+        echo "before yield\n";
+        yield;
+        echo "after yield\n";
+    } finally {
+        echo "finally run\n";
+    }
+
+    echo "code after finally\n";
+}
+
+$gen = gen();
+$gen->rewind();
+unset($gen);
+
+?>
+--EXPECT--
+before yield
+finally run
diff --git a/Zend/tests/generators/finally_uninterrupted.phpt b/Zend/tests/generators/finally_uninterrupted.phpt
new file mode 100644
index 0000000000000..64c94382aa010
--- /dev/null
+++ b/Zend/tests/generators/finally_uninterrupted.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Use of finally in generator without interrupt
+--FILE--
+<?php
+
+function gen() {
+    try {
+        throw new Exception;
+    } finally {
+        echo "finally run\n";
+    }
+
+    yield; // force generator
+}
+
+$gen = gen();
+$gen->rewind(); // force run
+
+?>
+--EXPECTF--
+finally run
+
+Fatal error: Uncaught exception 'Exception' in %s:%d
+Stack trace:
+#0 [internal function]: gen()
+#1 %s(%d): Generator->rewind()
+#2 {main}
+  thrown in %s on line %d
diff --git a/Zend/tests/generators/finally_with_return.phpt b/Zend/tests/generators/finally_with_return.phpt
new file mode 100644
index 0000000000000..b26a49f32fa3b
--- /dev/null
+++ b/Zend/tests/generators/finally_with_return.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Use of finally in generator with return
+--FILE--
+<?php
+
+function gen() {
+    try {
+        try {
+            echo "before return\n";
+            return;
+            echo "after return\n";
+        } finally {
+            echo "before return in inner finally\n";
+            return;
+            echo "after return in inner finally\n";
+        }
+    } finally {
+        echo "outer finally run\n";
+    }
+
+    echo "code after finally\n";
+
+    yield; // force generator
+}
+
+$gen = gen();
+$gen->rewind(); // force run
+
+?>
+--EXPECTF--
+before return
+before return in inner finally
+outer finally run
diff --git a/Zend/tests/generators/func_get_args.phpt b/Zend/tests/generators/func_get_args.phpt
new file mode 100644
index 0000000000000..f8d3fa7c146e7
--- /dev/null
+++ b/Zend/tests/generators/func_get_args.phpt
@@ -0,0 +1,21 @@
+--TEST--
+func_get_args() can be used inside generator functions
+--FILE--
+<?php
+
+function gen() {
+    var_dump(func_get_args());
+    yield; // trigger generator
+}
+
+$gen = gen("foo", "bar");
+$gen->rewind();
+
+?>
+--EXPECT--
+array(2) {
+  [0]=>
+  string(3) "foo"
+  [1]=>
+  string(3) "bar"
+}
diff --git a/Zend/tests/generators/generator_closure.phpt b/Zend/tests/generators/generator_closure.phpt
new file mode 100644
index 0000000000000..bf80066015f5e
--- /dev/null
+++ b/Zend/tests/generators/generator_closure.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Closures can be generators
+--FILE--
+<?php
+
+$genFactory = function() {
+    yield 1;
+    yield 2;
+    yield 3;
+};
+
+foreach ($genFactory() as $value) {
+    var_dump($value);
+}
+
+?>
+--EXPECT--
+int(1)
+int(2)
+int(3)
diff --git a/Zend/tests/generators/generator_closure_with_this.phpt b/Zend/tests/generators/generator_closure_with_this.phpt
new file mode 100644
index 0000000000000..d5a4861e80461
--- /dev/null
+++ b/Zend/tests/generators/generator_closure_with_this.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Non-static closures can be generators
+--FILE--
+<?php
+
+class Test {
+    public function getGenFactory() {
+        return function() {
+            yield $this;
+        };
+    }
+}
+
+$genFactory = (new Test)->getGenFactory();
+var_dump($genFactory()->current());
+
+?>
+--EXPECT--
+object(Test)#1 (0) {
+}
diff --git a/Zend/tests/generators/generator_in_multipleiterator.phpt b/Zend/tests/generators/generator_in_multipleiterator.phpt
new file mode 100644
index 0000000000000..611dbc9652743
--- /dev/null
+++ b/Zend/tests/generators/generator_in_multipleiterator.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Generators work properly in MultipleIterator
+--FILE--
+<?php
+
+function gen1() {
+    yield 'a';
+    yield 'aa';
+}
+
+function gen2() {
+    yield 'b';
+    yield 'bb';
+}
+
+$it = new MultipleIterator;
+$it->attachIterator(gen1());
+$it->attachIterator(gen2());
+
+foreach ($it as $values) {
+    var_dump($values);
+}
+
+?>
+--EXPECT--
+array(2) {
+  [0]=>
+  string(1) "a"
+  [1]=>
+  string(1) "b"
+}
+array(2) {
+  [0]=>
+  string(2) "aa"
+  [1]=>
+  string(2) "bb"
+}
diff --git a/Zend/tests/generators/generator_method.phpt b/Zend/tests/generators/generator_method.phpt
new file mode 100644
index 0000000000000..b8196c171ecdf
--- /dev/null
+++ b/Zend/tests/generators/generator_method.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Methods can be generators
+--FILE--
+<?php
+
+class Test implements IteratorAggregate {
+    protected $data;
+
+    public function __construct(array $data) {
+        $this->data = $data;
+    }
+
+    public function getIterator() {
+        foreach ($this->data as $value) {
+            yield $value;
+        }
+    }
+}
+
+$test = new Test(['foo', 'bar', 'baz']);
+foreach ($test as $value) {
+    var_dump($value);
+}
+
+?>
+--EXPECT--
+string(3) "foo"
+string(3) "bar"
+string(3) "baz"
diff --git a/Zend/tests/generators/generator_method_by_ref.phpt b/Zend/tests/generators/generator_method_by_ref.phpt
new file mode 100644
index 0000000000000..cfe52fe67ff82
--- /dev/null
+++ b/Zend/tests/generators/generator_method_by_ref.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Generator methods can yield by reference
+--FILE--
+<?php
+
+class Test implements IteratorAggregate {
+    protected $data;
+
+    public function __construct(array $data) {
+        $this->data = $data;
+    }
+
+    public function getData() {
+        return $this->data;
+    }
+
+    public function &getIterator() {
+        foreach ($this->data as $key => &$value) {
+            yield $key => $value;
+        }
+    }
+}
+
+$test = new Test([1, 2, 3, 4, 5]);
+foreach ($test as &$value) {
+    $value *= -1;
+}
+
+var_dump($test->getData());
+
+?>
+--EXPECT--
+array(5) {
+  [0]=>
+  int(-1)
+  [1]=>
+  int(-2)
+  [2]=>
+  int(-3)
+  [3]=>
+  int(-4)
+  [4]=>
+  &int(-5)
+}
diff --git a/Zend/tests/generators/generator_returns_generator.phpt b/Zend/tests/generators/generator_returns_generator.phpt
new file mode 100644
index 0000000000000..ad332a3be9246
--- /dev/null
+++ b/Zend/tests/generators/generator_returns_generator.phpt
@@ -0,0 +1,18 @@
+--TEST--
+A generator function returns a Generator object
+--FILE--
+<?php
+
+function gen() {
+    // execution is suspended here, so the following never gets run:
+    echo "Foo";
+	// trigger a generator
+    yield;
+}
+
+$generator = gen();
+var_dump($generator instanceof Generator);
+
+?>
+--EXPECT--
+bool(true)
diff --git a/Zend/tests/generators/generator_rewind.phpt b/Zend/tests/generators/generator_rewind.phpt
new file mode 100644
index 0000000000000..c4b5bbbdf4944
--- /dev/null
+++ b/Zend/tests/generators/generator_rewind.phpt
@@ -0,0 +1,62 @@
+--TEST--
+A generator can only be rewinded before or at the first yield
+--FILE--
+<?php
+
+function gen() {
+    echo "before yield\n";
+    yield;
+    echo "after yield\n";
+    yield;
+}
+
+$gen = gen();
+$gen->rewind();
+$gen->rewind();
+$gen->next();
+
+try {
+    $gen->rewind();
+} catch (Exception $e) {
+    echo "\n", $e, "\n\n";
+}
+
+function &gen2() {
+    $foo = 'bar';
+    yield $foo;
+    yield $foo;
+}
+
+$gen = gen2();
+foreach ($gen as $v) { }
+try {
+    foreach ($gen as $v) { }
+} catch (Exception $e) {
+    echo $e, "\n\n";
+}
+
+function gen3() {
+    echo "in generator\n";
+
+    if (false) yield;
+}
+
+$gen = gen3();
+$gen->rewind();
+
+?>
+--EXPECTF--
+before yield
+after yield
+
+exception 'Exception' with message 'Cannot rewind a generator that was already run' in %s:%d
+Stack trace:
+#0 %s(%d): Generator->rewind()
+#1 {main}
+
+exception 'Exception' with message 'Cannot traverse an already closed generator' in %s:%d
+Stack trace:
+#0 %s(%d): unknown()
+#1 {main}
+
+in generator
diff --git a/Zend/tests/generators/generator_send.phpt b/Zend/tests/generators/generator_send.phpt
new file mode 100644
index 0000000000000..074d815389711
--- /dev/null
+++ b/Zend/tests/generators/generator_send.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Values can be sent back to the generator
+--FILE--
+<?php
+
+function gen() {
+    var_dump(yield "yield foo");
+    var_dump(yield "yield bar");
+}
+
+$gen = gen();
+var_dump($gen->current());
+$gen->send("send bar");
+var_dump($gen->current());
+$gen->send("send foo");
+
+?>
+--EXPECT--
+string(9) "yield foo"
+string(8) "send bar"
+string(9) "yield bar"
+string(8) "send foo"
diff --git a/Zend/tests/generators/generator_static_method.phpt b/Zend/tests/generators/generator_static_method.phpt
new file mode 100644
index 0000000000000..cd9b450a76caf
--- /dev/null
+++ b/Zend/tests/generators/generator_static_method.phpt
@@ -0,0 +1,29 @@
+--TEST--
+A static method can be a generator
+--FILE--
+<?php
+
+class Test {
+    public static function gen() {
+        var_dump(get_class());
+        var_dump(get_called_class());
+        yield 1;
+        yield 2;
+        yield 3;
+    }
+}
+
+class ExtendedTest extends Test {
+}
+
+foreach (ExtendedTest::gen() as $i) {
+    var_dump($i);
+}
+
+?>
+--EXPECT--
+string(4) "Test"
+string(12) "ExtendedTest"
+int(1)
+int(2)
+int(3)
diff --git a/Zend/tests/generators/generator_throwing_during_function_call.phpt b/Zend/tests/generators/generator_throwing_during_function_call.phpt
new file mode 100644
index 0000000000000..bd0d2448b7d83
--- /dev/null
+++ b/Zend/tests/generators/generator_throwing_during_function_call.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Stack is cleaned up properly when an exception is thrown during a function call
+--FILE--
+<?php
+
+function throwException() {
+    throw new Exception('test');
+}
+
+function gen() {
+    yield 'foo';
+    strlen("foo", "bar", throwException());
+    yield 'bar';
+}
+
+$gen = gen();
+
+var_dump($gen->current());
+
+try {
+    $gen->next();
+} catch (Exception $e) {
+    echo 'Caught exception with message "', $e->getMessage(), '"', "\n";
+}
+
+var_dump($gen->current());
+
+?>
+--EXPECT--
+string(3) "foo"
+Caught exception with message "test"
+NULL
diff --git a/Zend/tests/generators/generator_throwing_exception.phpt b/Zend/tests/generators/generator_throwing_exception.phpt
new file mode 100644
index 0000000000000..f537c3fc7726e
--- /dev/null
+++ b/Zend/tests/generators/generator_throwing_exception.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Generators can throw exceptions
+--FILE--
+<?php
+
+function gen() {
+    yield 'foo';
+    throw new Exception('test');
+    yield 'bar';
+}
+
+$gen = gen();
+
+var_dump($gen->current());
+
+try {
+    $gen->next();
+} catch (Exception $e) {
+    echo 'Caught exception with message "', $e->getMessage(), '"', "\n";
+}
+
+var_dump($gen->current());
+
+?>
+--EXPECT--
+string(3) "foo"
+Caught exception with message "test"
+NULL
diff --git a/Zend/tests/generators/generator_throwing_in_foreach.phpt b/Zend/tests/generators/generator_throwing_in_foreach.phpt
new file mode 100644
index 0000000000000..dbf20c2ca1c65
--- /dev/null
+++ b/Zend/tests/generators/generator_throwing_in_foreach.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Exceptions throwing by generators during foreach iteration are properly handled
+--FILE--
+<?php
+
+function gen() {
+    throw new Exception("foo");
+    yield; // force generator
+}
+
+foreach (gen() as $value) { }
+
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'Exception' with message 'foo' in %s:%d
+Stack trace:
+#0 %s(%d): gen()
+#1 {main}
+  thrown in %s on line %d
+
diff --git a/Zend/tests/generators/generator_with_keys.phpt b/Zend/tests/generators/generator_with_keys.phpt
new file mode 100644
index 0000000000000..efb377679ec0d
--- /dev/null
+++ b/Zend/tests/generators/generator_with_keys.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Generators can also yield keys
+--FILE--
+<?php
+
+function reverse(array $array) {
+    end($array);
+    while (null !== $key = key($array)) {
+        yield $key => current($array);
+        prev($array);
+    }
+}
+
+$array = [
+    'foo' => 'bar',
+    'bar' => 'foo',
+];
+
+foreach (reverse($array) as $key => $value) {
+    echo $key, ' => ', $value, "\n";
+}
+
+?>
+--EXPECT--
+bar => foo
+foo => bar
diff --git a/Zend/tests/generators/no_foreach_var_leaks.phpt b/Zend/tests/generators/no_foreach_var_leaks.phpt
new file mode 100644
index 0000000000000..62743895ebcbd
--- /dev/null
+++ b/Zend/tests/generators/no_foreach_var_leaks.phpt
@@ -0,0 +1,19 @@
+--TEST--
+foreach() (and other) variables aren't leaked on premature close
+--FILE--
+<?php
+
+function gen(array $array) {
+	foreach ($array as $value) {
+		yield $value;
+	}
+}
+
+$gen = gen(['Foo', 'Bar']);
+var_dump($gen->current());
+
+// generator is closed here, without running SWITCH_FREE
+
+?>
+--EXPECT--
+string(3) "Foo"
diff --git a/Zend/tests/generators/send_after_close.phpt b/Zend/tests/generators/send_after_close.phpt
new file mode 100644
index 0000000000000..806baf8cee4ab
--- /dev/null
+++ b/Zend/tests/generators/send_after_close.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Calls to send() after close should do nothing
+--FILE--
+<?php
+
+function gen() { var_dump(yield); }
+
+$gen = gen();
+$gen->send('foo');
+$gen->send('bar');
+
+?>
+--EXPECT--
+string(3) "foo"
diff --git a/Zend/tests/generators/send_returns_current.phpt b/Zend/tests/generators/send_returns_current.phpt
new file mode 100644
index 0000000000000..27ba74bc1bd86
--- /dev/null
+++ b/Zend/tests/generators/send_returns_current.phpt
@@ -0,0 +1,20 @@
+--TEST--
+$generator->send() returns the yielded value
+--FILE--
+<?php
+
+function reverseEchoGenerator() {
+    $data = yield;
+    while (true) {
+        $data = (yield strrev($data));
+    }
+}
+
+$gen = reverseEchoGenerator();
+var_dump($gen->send('foo'));
+var_dump($gen->send('bar'));
+
+?>
+--EXPECT--
+string(3) "oof"
+string(3) "rab"
diff --git a/Zend/tests/generators/unused_return_value.phpt b/Zend/tests/generators/unused_return_value.phpt
new file mode 100644
index 0000000000000..ddce64542c9a0
--- /dev/null
+++ b/Zend/tests/generators/unused_return_value.phpt
@@ -0,0 +1,13 @@
+--TEST--
+There shouldn't be any leaks when the genertor's return value isn't used
+--FILE--
+<?php
+
+function gen($foo) { yield; }
+
+gen('foo'); // return value not used
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/Zend/tests/generators/xrange.phpt b/Zend/tests/generators/xrange.phpt
new file mode 100644
index 0000000000000..4d8b60fa909a8
--- /dev/null
+++ b/Zend/tests/generators/xrange.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Simple generator xrange() test
+--FILE--
+<?php
+
+function xrange($start, $end, $step = 1) {
+	for ($i = $start; $i <= $end; $i += $step) {
+		yield $i;
+	}
+}
+
+foreach (xrange(10, 20, 2) as $i) {
+	var_dump($i);
+}
+
+?>
+--EXPECT--
+int(10)
+int(12)
+int(14)
+int(16)
+int(18)
+int(20)
diff --git a/Zend/tests/generators/yield_array_offset_by_ref.phpt b/Zend/tests/generators/yield_array_offset_by_ref.phpt
new file mode 100644
index 0000000000000..544108e64d89b
--- /dev/null
+++ b/Zend/tests/generators/yield_array_offset_by_ref.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Array offsets can be yielded by reference
+--FILE--
+<?php
+
+function &gen(array &$array) {
+    yield $array[0];
+}
+
+$array = [1, 2, 3];
+$gen = gen($array);
+foreach ($gen as &$val) {
+    $val *= -1;
+}
+var_dump($array);
+
+?>
+--EXPECT--
+array(3) {
+  [0]=>
+  &int(-1)
+  [1]=>
+  int(2)
+  [2]=>
+  int(3)
+}
diff --git a/Zend/tests/generators/yield_by_reference.phpt b/Zend/tests/generators/yield_by_reference.phpt
new file mode 100644
index 0000000000000..dba0791c0d495
--- /dev/null
+++ b/Zend/tests/generators/yield_by_reference.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Generators can yield by-reference
+--FILE--
+<?php
+
+function &iter(array &$array) {
+    foreach ($array as $key => &$value) {
+        yield $key => $value;
+    }
+}
+
+$array = [1, 2, 3];
+$iter = iter($array);
+foreach ($iter as &$value) {
+    $value *= -1;
+}
+var_dump($array);
+
+$array = [1, 2, 3];
+foreach (iter($array) as &$value) {
+    $value *= -1;
+}
+var_dump($array);
+
+?>
+--EXPECT--
+array(3) {
+  [0]=>
+  int(-1)
+  [1]=>
+  int(-2)
+  [2]=>
+  &int(-3)
+}
+array(3) {
+  [0]=>
+  int(-1)
+  [1]=>
+  int(-2)
+  [2]=>
+  &int(-3)
+}
diff --git a/Zend/tests/generators/yield_during_function_call.phpt b/Zend/tests/generators/yield_during_function_call.phpt
new file mode 100644
index 0000000000000..21071f9fb4af6
--- /dev/null
+++ b/Zend/tests/generators/yield_during_function_call.phpt
@@ -0,0 +1,15 @@
+--TEST--
+"yield" can occur during a function call
+--FILE--
+<?php
+
+function gen() {
+	var_dump(str_repeat("x", yield));
+}
+
+$gen = gen();
+$gen->send(10);
+
+?>
+--EXPECT--
+string(10) "xxxxxxxxxx"
diff --git a/Zend/tests/generators/yield_during_method_call.phpt b/Zend/tests/generators/yield_during_method_call.phpt
new file mode 100644
index 0000000000000..5fbe84fff559b
--- /dev/null
+++ b/Zend/tests/generators/yield_during_method_call.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Yield can be used during a method call
+--FILE--
+<?php
+
+class A {
+    public function b($c) {
+        echo $c, "\n";
+    }
+}
+
+function gen() {
+    $a = new A;
+    $a->b(yield);
+}
+
+$gen = gen();
+$gen->send('foo');
+
+// test resource cleanup
+$gen = gen();
+$gen->rewind();
+unset($gen);
+
+// test cloning
+$g1 = gen();
+$g1->rewind();
+$g2 = clone $g1;
+unset($g1);
+$g2->send('bar');
+
+?>
+--EXPECT--
+foo
+bar
diff --git a/Zend/tests/generators/yield_in_finally.phpt b/Zend/tests/generators/yield_in_finally.phpt
new file mode 100644
index 0000000000000..805484ad1d150
--- /dev/null
+++ b/Zend/tests/generators/yield_in_finally.phpt
@@ -0,0 +1,29 @@
+--TEST--
+yield can be used in finally (apart from forced closes)
+--FILE--
+<?php
+
+function gen() {
+    try {
+        echo "before return\n";
+        return;
+        echo "after return\n";
+    } finally {
+        echo "before yield\n";
+        yield "yielded value";
+        echo "after yield\n";
+    }
+
+    echo "after finally\n";
+}
+
+$gen = gen();
+var_dump($gen->current());
+$gen->next();
+
+?>
+--EXPECTF--
+before return
+before yield
+string(%d) "yielded value"
+after yield
diff --git a/Zend/tests/generators/yield_in_parenthesis.phpt b/Zend/tests/generators/yield_in_parenthesis.phpt
new file mode 100644
index 0000000000000..4a603f4cc1a50
--- /dev/null
+++ b/Zend/tests/generators/yield_in_parenthesis.phpt
@@ -0,0 +1,23 @@
+--TEST--
+No additional parenthesis are required around yield if they are already present
+--FILE--
+<?php
+
+function gen() {
+    if (yield $foo); elseif (yield $foo);
+    if (yield $foo): elseif (yield $foo): endif;
+    while (yield $foo);
+    do {} while (yield $foo);
+    switch (yield $foo) {}
+    (yield $foo);
+    die(yield $foo);
+    func(yield $foo);
+    $foo->func(yield $foo);
+    new Foo(yield $foo);
+}
+
+echo "Done";
+
+?>
+--EXPECT--
+Done
diff --git a/Zend/tests/generators/yield_ref_function_call_by_reference.phpt b/Zend/tests/generators/yield_ref_function_call_by_reference.phpt
new file mode 100644
index 0000000000000..e371affd92c8e
--- /dev/null
+++ b/Zend/tests/generators/yield_ref_function_call_by_reference.phpt
@@ -0,0 +1,24 @@
+--TEST--
+The result of a by-ref function call can be yielded just fine
+--FILE--
+<?php
+
+function &nop(&$var) {
+    return $var;
+}
+
+function &gen(&$var) {
+    yield nop($var);
+}
+
+$var = "foo";
+$gen = gen($var);
+foreach ($gen as &$varRef) {
+    $varRef = "bar";
+}
+
+var_dump($var);
+
+?>
+--EXPECT--
+string(3) "bar"
diff --git a/Zend/tests/generators/yield_without_value.phpt b/Zend/tests/generators/yield_without_value.phpt
new file mode 100644
index 0000000000000..510c755bd3fe9
--- /dev/null
+++ b/Zend/tests/generators/yield_without_value.phpt
@@ -0,0 +1,27 @@
+--TEST--
+yield can be used without a value
+--FILE--
+<?php
+
+function recv() {
+    while (true) {
+        var_dump(yield);
+    }
+}
+
+$reciever = recv();
+var_dump($reciever->current());
+$reciever->send(1);
+var_dump($reciever->current());
+$reciever->send(2);
+var_dump($reciever->current());
+$reciever->send(3);
+
+?>
+--EXPECT--
+NULL
+int(1)
+NULL
+int(2)
+NULL
+int(3)
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index b87b1908b6bde..265e7e6b72db3 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -1722,7 +1722,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
 	}
 
 	{
-		/* Push a seperator to the switch and foreach stacks */
+		/* Push a seperator to the switch stack */
 		zend_switch_entry switch_entry;
 
 		switch_entry.cond.op_type = IS_UNUSED;
@@ -1730,16 +1730,16 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
 		switch_entry.control_var = 0;
 
 		zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry, sizeof(switch_entry));
+	}
 
-		{
-			/* Foreach stack separator */
-			zend_op dummy_opline;
+	{
+		/* Push a separator to the foreach stack */
+		zend_op dummy_opline;
 
-			dummy_opline.result_type = IS_UNUSED;
-			dummy_opline.op1_type = IS_UNUSED;
+		dummy_opline.result_type = IS_UNUSED;
+		dummy_opline.op1_type = IS_UNUSED;
 
-			zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
-		}
+		zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
 	}
 
 	if (CG(doc_comment)) {
@@ -2611,9 +2611,12 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) /* {{{ */
 {
 	zend_op *opline;
 	int start_op_number, end_op_number;
+	zend_bool returns_reference = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
+
+	/* The error for use of return inside a generator is thrown in pass_two. */
 
 	if (do_end_vparse) {
-		if ((CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) && !zend_is_function_or_method_call(expr)) {
+		if (returns_reference && !zend_is_function_or_method_call(expr)) {
 			zend_do_end_variable_parse(expr, BP_VAR_W, 0 TSRMLS_CC);
 		} else {
 			zend_do_end_variable_parse(expr, BP_VAR_R, 0 TSRMLS_CC);
@@ -2638,7 +2641,7 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) /* {{{ */
 
 	opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
-	opline->opcode = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) ? ZEND_RETURN_BY_REF : ZEND_RETURN;
+	opline->opcode = returns_reference ? ZEND_RETURN_BY_REF : ZEND_RETURN;
 
 	if (expr) {
 		SET_NODE(opline->op1, expr);
@@ -2655,6 +2658,50 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
+void zend_do_yield(znode *result, znode *value, const znode *key, zend_bool is_variable TSRMLS_DC) /* {{{ */
+{
+	zend_op *opline;
+
+	if (!CG(active_op_array)->function_name) {
+		zend_error(E_COMPILE_ERROR, "The \"yield\" expression can only be used inside a function");
+	}
+
+	CG(active_op_array)->fn_flags |= ZEND_ACC_GENERATOR;
+
+	if (is_variable) {
+		if ((CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) && !zend_is_function_or_method_call(value)) {
+			zend_do_end_variable_parse(value, BP_VAR_W, 0 TSRMLS_CC);
+		} else {
+			zend_do_end_variable_parse(value, BP_VAR_R, 0 TSRMLS_CC);
+		}
+	}
+
+	opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+	opline->opcode = ZEND_YIELD;
+
+	if (value) {
+		SET_NODE(opline->op1, value);
+
+		if (is_variable && zend_is_function_or_method_call(value)) {
+			opline->extended_value = ZEND_RETURNS_FUNCTION;
+		}
+	} else {
+		SET_UNUSED(opline->op1);
+	}
+
+	if (key) {
+		SET_NODE(opline->op2, key);
+	} else {
+		SET_UNUSED(opline->op2);
+	}
+
+	opline->result_type = IS_VAR;
+	opline->result.var = get_temporary_variable(CG(active_op_array));
+	GET_NODE(result, opline->result);
+}
+/* }}} */
+
 static int zend_add_try_element(zend_uint try_op TSRMLS_DC) /* {{{ */
 {
 	int try_catch_offset = CG(active_op_array)->last_try_catch++;
@@ -6289,9 +6336,7 @@ void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token
 
 	if (value->EA & ZEND_PARSED_REFERENCE_VARIABLE) {
 		assign_by_ref = 1;
-		if (!(opline-1)->extended_value) {
-			zend_error(E_COMPILE_ERROR, "Cannot create references to elements of a temporary array expression");
-		}
+
 		/* Mark extended_value for assign-by-reference */
 		opline->extended_value |= ZEND_FE_FETCH_BYREF;
 		CG(active_op_array)->opcodes[foreach_token->u.op.opline_num].extended_value |= ZEND_FE_RESET_REFERENCE;
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 15c2ab7bc7998..664f9b8469855 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -196,6 +196,7 @@ typedef struct _zend_try_catch_element {
 
 
 #define ZEND_ACC_CLOSURE              0x100000
+#define ZEND_ACC_GENERATOR            0x800000
 
 /* function flag for internal user call handlers __call, __callstatic */
 #define ZEND_ACC_CALL_VIA_HANDLER     0x200000
@@ -494,6 +495,7 @@ void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_c
 int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC);
 void zend_do_end_function_call(znode *function_name, znode *result, const znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC);
 void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC);
+void zend_do_yield(znode *result, znode *value, const znode *key, zend_bool is_variable TSRMLS_DC);
 void zend_do_handle_exception(TSRMLS_D);
 
 void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference, int is_static TSRMLS_DC);
diff --git a/Zend/zend_default_classes.c b/Zend/zend_default_classes.c
index 73a765811e853..bcc43ea7db142 100644
--- a/Zend/zend_default_classes.c
+++ b/Zend/zend_default_classes.c
@@ -25,6 +25,7 @@
 #include "zend_interfaces.h"
 #include "zend_exceptions.h"
 #include "zend_closures.h"
+#include "zend_generators.h"
 
 
 ZEND_API void zend_register_default_classes(TSRMLS_D)
@@ -33,6 +34,7 @@ ZEND_API void zend_register_default_classes(TSRMLS_D)
 	zend_register_default_exception(TSRMLS_C);
 	zend_register_iterator_wrapper(TSRMLS_C);
 	zend_register_closure_ce(TSRMLS_C);
+	zend_register_generator_ce(TSRMLS_C);
 }
 
 /*
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index fbc73258c7090..149b91233cc79 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -35,6 +35,7 @@
 #include "zend_exceptions.h"
 #include "zend_interfaces.h"
 #include "zend_closures.h"
+#include "zend_generators.h"
 #include "zend_vm.h"
 #include "zend_dtrace.h"
 
@@ -1536,6 +1537,50 @@ ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const t
 	return get_zval_ptr_ptr(op_type, node, Ts, should_free, type);
 }
 
+void zend_clean_and_cache_symbol_table(HashTable *symbol_table TSRMLS_DC) /* {{{ */
+{
+	if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) {
+		zend_hash_destroy(symbol_table);
+		FREE_HASHTABLE(symbol_table);
+	} else {
+		/* clean before putting into the cache, since clean
+		   could call dtors, which could use cached hash */
+		zend_hash_clean(symbol_table);
+		*(++EG(symtable_cache_ptr)) = symbol_table;
+	}
+}
+/* }}} */
+
+void zend_free_compiled_variables(zval ***CVs, int num) /* {{{ */
+{
+	int i;
+	for (i = 0; i < num; ++i) {
+		if (CVs[i]) {
+			zval_ptr_dtor(CVs[i]);
+		}
+	}
+}
+/* }}} */
+
+void** zend_copy_arguments(void **arguments_end) /* {{{ */
+{
+	int arguments_count = (int) (zend_uintptr_t) *arguments_end;
+	size_t arguments_size = (arguments_count + 1) * sizeof(void **);
+	void **arguments_start = arguments_end - arguments_count;
+	void **copied_arguments_start = emalloc(arguments_size);
+	void **copied_arguments_end = copied_arguments_start + arguments_count;
+	int i;
+
+	memcpy(copied_arguments_start, arguments_start, arguments_size);
+
+	for (i = 0; i < arguments_count; i++) {
+		Z_ADDREF_P((zval *) arguments_start[i]);
+	}
+
+	return copied_arguments_end;
+}
+/* }}} */
+
 /*
  * Local variables:
  * tab-width: 4
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h
index 7d427388bdadd..4cfc52b6a3b69 100644
--- a/Zend/zend_execute.h
+++ b/Zend/zend_execute.h
@@ -55,7 +55,9 @@ ZEND_API extern void (*zend_execute_internal)(zend_execute_data *execute_data_pt
 void init_executor(TSRMLS_D);
 void shutdown_executor(TSRMLS_D);
 void shutdown_destructors(TSRMLS_D);
+zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC);
 ZEND_API void execute(zend_op_array *op_array TSRMLS_DC);
+ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC);
 ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);
 ZEND_API int zend_is_true(zval *op);
 #define safe_free_zval_ptr(p) safe_free_zval_ptr_rel(p ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
@@ -431,6 +433,10 @@ ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const t
 
 ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS);
 
+void zend_clean_and_cache_symbol_table(HashTable *symbol_table TSRMLS_DC);
+void zend_free_compiled_variables(zval ***CVs, int num);
+void **zend_copy_arguments(void **arguments_end);
+
 #define CACHED_PTR(num) \
 	EG(active_op_array)->run_time_cache[(num)]
 
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 1deee2a86c89e..fb0c18b27cc3f 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -31,6 +31,7 @@
 #include "zend_extensions.h"
 #include "zend_exceptions.h"
 #include "zend_closures.h"
+#include "zend_generators.h"
 #include "zend_vm.h"
 #include "zend_float.h"
 #ifdef HAVE_SYS_TIME_H
@@ -955,7 +956,13 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
 		EG(return_value_ptr_ptr) = fci->retval_ptr_ptr;
 		EG(active_op_array) = (zend_op_array *) EX(function_state).function;
 		original_opline_ptr = EG(opline_ptr);
-		zend_execute(EG(active_op_array) TSRMLS_CC);
+
+		if (EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) {
+			*fci->retval_ptr_ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
+		} else {
+			zend_execute(EG(active_op_array) TSRMLS_CC);
+		}
+
 		if (!fci->symbol_table && EG(active_symbol_table)) {
 			if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
 				zend_hash_destroy(EG(active_symbol_table));
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
new file mode 100644
index 0000000000000..c22d745bc362d
--- /dev/null
+++ b/Zend/zend_generators.c
@@ -0,0 +1,838 @@
+/*
+   +----------------------------------------------------------------------+
+   | Zend Engine                                                          |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.00 of the Zend license,     |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.zend.com/license/2_00.txt.                                |
+   | If you did not receive a copy of the Zend license and are unable to  |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@zend.com so we can mail you a copy immediately.              |
+   +----------------------------------------------------------------------+
+   | Authors: Nikita Popov <nikic@php.net>                                |
+   +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#include "zend.h"
+#include "zend_API.h"
+#include "zend_interfaces.h"
+#include "zend_exceptions.h"
+#include "zend_generators.h"
+
+ZEND_API zend_class_entry *zend_ce_generator;
+static zend_object_handlers zend_generator_handlers;
+
+void zend_generator_close(zend_generator *generator, zend_bool finished_execution TSRMLS_DC) /* {{{ */
+{
+	if (generator->execute_data) {
+		zend_execute_data *execute_data = generator->execute_data;
+		zend_op_array *op_array = execute_data->op_array;
+
+		if (!finished_execution) {
+			if (op_array->has_finally_block) {
+				/* -1 required because we want the last run opcode, not the
+				 * next to-be-run one. */
+				zend_uint op_num = execute_data->opline - op_array->opcodes - 1;
+				zend_uint finally_op_num = 0;
+
+				/* Find next finally block */
+				int i;
+				for (i = 0; i < op_array->last_try_catch; i++) {
+					zend_try_catch_element *try_catch = &op_array->try_catch_array[i];
+
+					if (op_num < try_catch->try_op) {
+						break;
+					}
+
+					if (op_num < try_catch->finally_op) {
+						finally_op_num = try_catch->finally_op;
+					}
+				}
+
+				/* If a finally block was found we jump directly to it and
+				 * resume the generator. Furthermore we abort this close call
+				 * because the generator will already be closed somewhere in
+				 * the resume. */
+				if (finally_op_num) {
+					execute_data->opline = &op_array->opcodes[finally_op_num];
+					execute_data->leaving = ZEND_RETURN;
+					generator->flags |= ZEND_GENERATOR_FORCED_CLOSE;
+					zend_generator_resume(generator TSRMLS_CC);
+					return;
+				}
+			}
+		}
+
+		if (!execute_data->symbol_table) {
+			zend_free_compiled_variables(execute_data->CVs, op_array->last_var);
+		} else {
+			zend_clean_and_cache_symbol_table(execute_data->symbol_table TSRMLS_CC);
+		}
+
+		if (execute_data->current_this) {
+			zval_ptr_dtor(&execute_data->current_this);
+		}
+
+		if (execute_data->object) {
+			zval_ptr_dtor(&execute_data->object);
+		}
+
+		/* If the generator is closed before it can finish execution (reach
+		 * a return statement) we have to free loop variables manually, as
+		 * we don't know whether the SWITCH_FREE / FREE opcodes have run */
+		if (!finished_execution) {
+			/* -1 required because we want the last run opcode, not the
+			 * next to-be-run one. */
+			zend_uint op_num = execute_data->opline - op_array->opcodes - 1;
+
+			int i;
+			for (i = 0; i < op_array->last_brk_cont; ++i) {
+				zend_brk_cont_element *brk_cont = op_array->brk_cont_array + i;
+
+				if (brk_cont->start < 0) {
+					continue;
+				} else if (brk_cont->start > op_num) {
+					break;
+				} else if (brk_cont->brk > op_num) {
+					zend_op *brk_opline = op_array->opcodes + brk_cont->brk;
+
+					switch (brk_opline->opcode) {
+						case ZEND_SWITCH_FREE:
+							{
+								temp_variable *var = (temp_variable *) ((char *) execute_data->Ts + brk_opline->op1.var);
+								zval_ptr_dtor(&var->var.ptr);
+							}
+							break;
+						case ZEND_FREE:
+							{
+								temp_variable *var = (temp_variable *) ((char *) execute_data->Ts + brk_opline->op1.var);
+								zval_dtor(&var->tmp_var);
+							}
+							break;
+					}
+				}
+			}
+		}
+
+		/* Clear any backed up stack arguments */
+		if (generator->backed_up_stack) {
+			zval **zvals = (zval **) generator->backed_up_stack;
+			size_t zval_num = generator->backed_up_stack_size / sizeof(zval *);
+			int i;
+
+			for (i = 0; i < zval_num; i++) {
+				zval_ptr_dtor(&zvals[i]);
+			}
+
+			efree(generator->backed_up_stack);
+		}
+
+		/* We have added an additional stack frame in prev_execute_data, so we
+		 * have to free it. It also contains the arguments passed to the
+		 * generator (for func_get_args) so those have to be freed too. */
+		{
+			zend_execute_data *prev_execute_data = execute_data->prev_execute_data;
+			void **arguments = prev_execute_data->function_state.arguments;
+
+			if (arguments) {
+				int arguments_count = (int) (zend_uintptr_t) *arguments;
+				zval **arguments_start = (zval **) (arguments - arguments_count);
+				int i;
+
+				for (i = 0; i < arguments_count; ++i) {
+					zval_ptr_dtor(arguments_start + i);
+				}
+
+				efree(arguments_start);
+			}
+
+			efree(prev_execute_data);
+		}
+
+		efree(execute_data);
+		generator->execute_data = NULL;
+	}
+
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+		generator->value = NULL;
+	}
+
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+		generator->key = NULL;
+	}
+}
+/* }}} */
+
+static void zend_generator_free_storage(zend_generator *generator TSRMLS_DC) /* {{{ */
+{
+	zend_generator_close(generator, 0 TSRMLS_CC);
+
+	zend_object_std_dtor(&generator->std TSRMLS_CC);
+	efree(generator);
+}
+/* }}} */
+
+static void zend_generator_clone_storage(zend_generator *orig, zend_generator **clone_ptr) /* {{{ */
+{
+	zend_generator *clone = emalloc(sizeof(zend_generator));
+	memcpy(clone, orig, sizeof(zend_generator));
+
+	if (orig->execute_data) {
+		/* Create a few shorter aliases to the old execution data */
+		zend_execute_data *execute_data = orig->execute_data;
+		zend_op_array *op_array = execute_data->op_array;
+		HashTable *symbol_table = execute_data->symbol_table;
+
+		/* Alloc separate execution context, as well as separate sections for
+		 * compiled variables and temporary variables */
+		size_t execute_data_size = ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data));
+		size_t CVs_size = ZEND_MM_ALIGNED_SIZE(sizeof(zval **) * op_array->last_var * (symbol_table ? 1 : 2));
+		size_t Ts_size = ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T;
+		size_t total_size = execute_data_size + CVs_size + Ts_size;
+
+		clone->execute_data = emalloc(total_size);
+
+		/* Copy the zend_execute_data struct */
+		memcpy(clone->execute_data, execute_data, execute_data_size);
+
+		/* Set the pointers to the memory segments for the compiled and
+		 * temporary variables (which are located after the execute_data) */
+		clone->execute_data->CVs = (zval ***) ((char *) clone->execute_data + execute_data_size);
+		clone->execute_data->Ts = (temp_variable *) ((char *) clone->execute_data->CVs + CVs_size);
+
+		/* Zero out the compiled variables section */
+		memset(clone->execute_data->CVs, 0, sizeof(zval **) * op_array->last_var);
+
+		if (!symbol_table) {
+			int i;
+
+			/* Copy compiled variables */
+			for (i = 0; i < op_array->last_var; i++) {
+				if (execute_data->CVs[i]) {
+					clone->execute_data->CVs[i] = (zval **) clone->execute_data->CVs + op_array->last_var + i;
+					*clone->execute_data->CVs[i] = (zval *) orig->execute_data->CVs[op_array->last_var + i];
+					Z_ADDREF_PP(clone->execute_data->CVs[i]);
+				}
+			}
+		} else {
+			/* Copy symbol table */
+			ALLOC_HASHTABLE(clone->execute_data->symbol_table);
+			zend_hash_init(clone->execute_data->symbol_table, zend_hash_num_elements(symbol_table), NULL, ZVAL_PTR_DTOR, 0);
+			zend_hash_copy(clone->execute_data->symbol_table, symbol_table, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+
+			/* Update zval** pointers for compiled variables */
+			{
+				int i;
+				for (i = 0; i < op_array->last_var; i++) {
+					if (zend_hash_quick_find(clone->execute_data->symbol_table, op_array->vars[i].name, op_array->vars[i].name_len + 1, op_array->vars[i].hash_value, (void **) &clone->execute_data->CVs[i]) == FAILURE) {
+						clone->execute_data->CVs[i] = NULL;
+					}
+				}
+			}
+		}
+
+		/* Copy the temporary variables */
+		memcpy(clone->execute_data->Ts, orig->execute_data->Ts, Ts_size);
+
+		/* Add references to loop variables */
+		{
+			zend_uint op_num = execute_data->opline - op_array->opcodes;
+
+			int i;
+			for (i = 0; i < op_array->last_brk_cont; ++i) {
+				zend_brk_cont_element *brk_cont = op_array->brk_cont_array + i;
+
+				if (brk_cont->start < 0) {
+					continue;
+				} else if (brk_cont->start > op_num) {
+					break;
+				} else if (brk_cont->brk > op_num) {
+					zend_op *brk_opline = op_array->opcodes + brk_cont->brk;
+
+					if (brk_opline->opcode == ZEND_SWITCH_FREE) {
+						temp_variable *var = (temp_variable *) ((char *) execute_data->Ts + brk_opline->op1.var);
+
+						Z_ADDREF_P(var->var.ptr);
+					}
+				}
+			}
+		}
+
+		if (orig->backed_up_stack) {
+			/* Copy backed up stack */
+			clone->backed_up_stack = emalloc(orig->backed_up_stack_size);
+			memcpy(clone->backed_up_stack, orig->backed_up_stack, orig->backed_up_stack_size);
+
+			/* Add refs to stack variables */
+			{
+				zval **zvals = (zval **) orig->backed_up_stack;
+				size_t zval_num = orig->backed_up_stack_size / sizeof(zval *);
+				int i;
+
+				for (i = 0; i < zval_num; i++) {
+					Z_ADDREF_P(zvals[i]);
+				}
+			}
+		}
+
+		/* Update the send_target to use the temporary variable with the same
+		 * offset as the original generator, but in our temporary variable
+		 * memory segment. */
+		if (orig->send_target) {
+			size_t offset = (char *) orig->send_target - (char *) execute_data->Ts;
+			clone->send_target = (temp_variable *) (
+				(char *) clone->execute_data->Ts + offset
+			);
+			Z_ADDREF_P(clone->send_target->var.ptr);
+		}
+
+		if (execute_data->current_this) {
+			Z_ADDREF_P(execute_data->current_this);
+		}
+
+		if (execute_data->object) {
+			Z_ADDREF_P(execute_data->object);
+		}
+
+		/* Prev execute data contains an additional stack frame (for proper
+		 * backtraces) which has to be copied. */
+		clone->execute_data->prev_execute_data = emalloc(sizeof(zend_execute_data));
+		memcpy(clone->execute_data->prev_execute_data, execute_data->prev_execute_data, sizeof(zend_execute_data));
+
+		/* It also contains the arguments passed to the generator, which also
+		 * have to be copied */
+		if (execute_data->prev_execute_data->function_state.arguments) {
+			clone->execute_data->prev_execute_data->function_state.arguments
+				= zend_copy_arguments(execute_data->prev_execute_data->function_state.arguments);
+		}
+	}
+
+	/* The value and key are known not to be references, so simply add refs */
+	if (orig->value) {
+		Z_ADDREF_P(orig->value);
+	}
+
+	if (orig->key) {
+		Z_ADDREF_P(orig->key);
+	}
+
+	*clone_ptr = clone;
+}
+/* }}} */
+
+static zend_object_value zend_generator_create(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
+{
+	zend_generator *generator;
+	zend_object_value object;
+
+	generator = emalloc(sizeof(zend_generator));
+	memset(generator, 0, sizeof(zend_generator));
+
+	/* The key will be incremented on first use, so it'll start at 0 */
+	generator->largest_used_integer_key = -1;
+
+	zend_object_std_init(&generator->std, class_type TSRMLS_CC);
+
+	object.handle = zend_objects_store_put(generator, NULL,
+		(zend_objects_free_object_storage_t) zend_generator_free_storage,
+		(zend_objects_store_clone_t)         zend_generator_clone_storage
+		TSRMLS_CC
+	);
+	object.handlers = &zend_generator_handlers;
+
+	return object;
+}
+/* }}} */
+
+/* Requires globals EG(scope), EG(current_scope), EG(This),
+ * EG(active_symbol_table) and EG(current_execute_data). */
+zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	zval *return_value;
+	zend_generator *generator;
+
+	/* Create new execution context. We have to back up and restore
+	 * EG(current_execute_data) and EG(opline_ptr) here because the function
+	 * modifies it. */
+	zend_execute_data *current_execute_data = EG(current_execute_data);
+	zend_op **opline_ptr = EG(opline_ptr);
+	zend_execute_data *execute_data = zend_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC);
+	EG(current_execute_data) = current_execute_data;
+	EG(opline_ptr) = opline_ptr;
+
+	ALLOC_INIT_ZVAL(return_value);
+	object_init_ex(return_value, zend_ce_generator);
+
+	if (EG(This)) {
+		Z_ADDREF_P(EG(This));
+	}
+
+	/* Back up executor globals. */
+	execute_data->current_scope = EG(scope);
+	execute_data->current_called_scope = EG(called_scope);
+	execute_data->symbol_table = EG(active_symbol_table);
+	execute_data->current_this = EG(This);
+
+	/* Save execution context in generator object. */
+	generator = (zend_generator *) zend_object_store_get_object(return_value TSRMLS_CC);
+	generator->execute_data = execute_data;
+
+	/* We have to add another stack frame so the generator function shows
+	 * up in backtraces and func_get_all() can access the function
+	 * arguments. */
+	execute_data->prev_execute_data = emalloc(sizeof(zend_execute_data));
+	memset(execute_data->prev_execute_data, 0, sizeof(zend_execute_data));
+	execute_data->prev_execute_data->function_state.function = (zend_function *) op_array;
+	if (EG(current_execute_data)) {
+		execute_data->prev_execute_data->function_state.arguments = zend_copy_arguments(EG(current_execute_data)->function_state.arguments);
+	} else {
+		execute_data->prev_execute_data->function_state.arguments = NULL;
+	}
+
+	return return_value;
+}
+/* }}} */
+
+static zend_function *zend_generator_get_constructor(zval *object TSRMLS_DC) /* {{{ */
+{
+	zend_error(E_RECOVERABLE_ERROR, "The \"Generator\" class is reserved for internal use and cannot be manually instantiated");
+
+	return NULL;
+}
+/* }}} */
+
+void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{ */
+{
+	/* The generator is already closed, thus can't resume */
+	if (!generator->execute_data) {
+		return;
+	}
+
+	if (generator->flags & ZEND_GENERATOR_CURRENTLY_RUNNING) {
+		zend_error(E_ERROR, "Cannot resume an already running generator");
+	}
+
+	/* Drop the AT_FIRST_YIELD flag */
+	generator->flags &= ~ZEND_GENERATOR_AT_FIRST_YIELD;
+
+	{
+		/* Backup executor globals */
+		zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
+		zend_execute_data *original_execute_data = EG(current_execute_data);
+		zend_op **original_opline_ptr = EG(opline_ptr);
+		zend_op_array *original_active_op_array = EG(active_op_array);
+		HashTable *original_active_symbol_table = EG(active_symbol_table);
+		zval *original_This = EG(This);
+		zend_class_entry *original_scope = EG(scope);
+		zend_class_entry *original_called_scope = EG(called_scope);
+
+		/* Remember the current stack position so we can back up pushed args */
+		generator->original_stack_top = zend_vm_stack_top(TSRMLS_C);
+
+		/* If there is a backed up stack copy it to the VM stack */
+		if (generator->backed_up_stack) {
+			void *stack = zend_vm_stack_alloc(generator->backed_up_stack_size TSRMLS_CC);
+			memcpy(stack, generator->backed_up_stack, generator->backed_up_stack_size);
+			efree(generator->backed_up_stack);
+			generator->backed_up_stack = NULL;
+		}
+
+		/* We (mis)use the return_value_ptr_ptr to provide the generator object
+		 * to the executor, so YIELD will be able to set the yielded value */
+		EG(return_value_ptr_ptr) = (zval **) generator;
+
+		/* Set executor globals */
+		EG(current_execute_data) = generator->execute_data;
+		EG(opline_ptr) = &generator->execute_data->opline;
+		EG(active_op_array) = generator->execute_data->op_array;
+		EG(active_symbol_table) = generator->execute_data->symbol_table;
+		EG(This) = generator->execute_data->current_this;
+		EG(scope) = generator->execute_data->current_scope;
+		EG(called_scope) = generator->execute_data->current_called_scope;
+
+		/* We want the backtrace to look as if the generator function was
+		 * called from whatever method we are current running (e.g. next()).
+		 * The first prev_execute_data contains an additional stack frame,
+		 * which makes the generator function show up in the backtrace and
+		 * makes the arguments available to func_get_args(). So we have to
+		 * set the prev_execute_data of that prev_execute_data :) */
+		generator->execute_data->prev_execute_data->prev_execute_data = original_execute_data;
+
+		/* Resume execution */
+		generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING;
+		execute_ex(generator->execute_data TSRMLS_CC);
+		generator->flags &= ~ZEND_GENERATOR_CURRENTLY_RUNNING;
+
+		/* Restore executor globals */
+		EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
+		EG(current_execute_data) = original_execute_data;
+		EG(opline_ptr) = original_opline_ptr;
+		EG(active_op_array) = original_active_op_array;
+		EG(active_symbol_table) = original_active_symbol_table;
+		EG(This) = original_This;
+		EG(scope) = original_scope;
+		EG(called_scope) = original_called_scope;
+
+		/* The stack top before and after the execution differ, i.e. there are
+		 * arguments pushed to the stack. */
+		if (generator->original_stack_top != zend_vm_stack_top(TSRMLS_C)) {
+			generator->backed_up_stack_size = (zend_vm_stack_top(TSRMLS_C) - generator->original_stack_top) * sizeof(void *);
+			generator->backed_up_stack = emalloc(generator->backed_up_stack_size);
+			memcpy(generator->backed_up_stack, generator->original_stack_top, generator->backed_up_stack_size);
+			zend_vm_stack_free(generator->original_stack_top TSRMLS_CC);
+		}
+
+		/* If an exception was thrown in the generator we have to internally
+		 * rethrow it in the parent scope. */
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			zend_throw_exception_internal(NULL TSRMLS_CC);
+		}
+	}
+}
+/* }}} */
+
+static void zend_generator_ensure_initialized(zend_generator *generator TSRMLS_DC) /* {{{ */
+{
+	if (generator->execute_data && !generator->value) {
+		zend_generator_resume(generator TSRMLS_CC);
+		generator->flags |= ZEND_GENERATOR_AT_FIRST_YIELD;
+	}
+}
+/* }}} */
+
+static void zend_generator_rewind(zend_generator *generator TSRMLS_DC) /* {{{ */
+{
+	zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+	if (!(generator->flags & ZEND_GENERATOR_AT_FIRST_YIELD)) {
+		zend_throw_exception(NULL, "Cannot rewind a generator that was already run", 0 TSRMLS_CC);
+	}
+}
+/* }}} */
+
+/* {{{ proto void Generator::rewind()
+ * Rewind the generator */
+ZEND_METHOD(Generator, rewind)
+{
+	zend_generator *generator;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+	generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+	zend_generator_rewind(generator TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto bool Generator::valid()
+ * Check whether the generator is valid */
+ZEND_METHOD(Generator, valid)
+{
+	zend_generator *generator;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+	generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+	zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+	RETURN_BOOL(generator->value != NULL);
+}
+/* }}} */
+
+/* {{{ proto mixed Generator::current()
+ * Get the current value */
+ZEND_METHOD(Generator, current)
+{
+	zend_generator *generator;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+	generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+	zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+	if (generator->value) {
+		RETURN_ZVAL(generator->value, 1, 0);
+	}
+}
+/* }}} */
+
+/* {{{ proto mixed Generator::key()
+ * Get the current key */
+ZEND_METHOD(Generator, key)
+{
+	zend_generator *generator;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+	generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+	zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+	if (generator->key) {
+		RETURN_ZVAL(generator->key, 1, 0);
+	}
+}
+/* }}} */
+
+/* {{{ proto void Generator::next()
+ * Advances the generator */
+ZEND_METHOD(Generator, next)
+{
+	zend_generator *generator;
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+	generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+	zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+	zend_generator_resume(generator TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto mixed Generator::send()
+ * Sends a value to the generator */
+ZEND_METHOD(Generator, send)
+{
+	zval *value;
+	zend_generator *generator;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
+		return;
+	}
+
+	generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+	zend_generator_ensure_initialized(generator TSRMLS_CC); 
+
+	/* The generator is already closed, thus can't send anything */
+	if (!generator->execute_data) {
+		return;
+	}
+
+	/* The sent value was initialized to NULL, so dtor that */
+	zval_ptr_dtor(&generator->send_target->var.ptr);
+
+	/* Set new sent value */
+	Z_ADDREF_P(value);
+	generator->send_target->var.ptr = value;
+	generator->send_target->var.ptr_ptr = &value;
+
+	zend_generator_resume(generator TSRMLS_CC);
+
+	if (generator->value) {
+		RETURN_ZVAL(generator->value, 1, 0);
+	}
+}
+/* }}} */
+
+/* {{{ proto void Generator::__wakeup()
+ * Throws an Exception as generators can't be serialized */
+ZEND_METHOD(Generator, __wakeup)
+{
+	/* Just specifying the zend_class_unserialize_deny handler is not enough,
+	 * because it is only invoked for C unserialization. For O the error has
+	 * to be thrown in __wakeup. */
+
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
+
+	zend_throw_exception(NULL, "Unserialization of 'Generator' is not allowed", 0 TSRMLS_CC);
+}
+/* }}} */
+
+/* get_iterator implementation */
+
+typedef struct _zend_generator_iterator {
+	zend_object_iterator intern;
+
+	/* The generator object zval has to be stored, because the iterator is
+	 * holding a ref to it, which has to be dtored. */
+	zval *object;
+} zend_generator_iterator;
+
+static void zend_generator_iterator_dtor(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
+{
+	zval *object = ((zend_generator_iterator *) iterator)->object;
+
+	zval_ptr_dtor(&object);
+
+	efree(iterator);
+}
+/* }}} */
+
+static int zend_generator_iterator_valid(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
+{
+	zend_generator *generator = (zend_generator *) iterator->data;
+
+	zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+	return generator->value != NULL ? SUCCESS : FAILURE;
+}
+/* }}} */
+
+static void zend_generator_iterator_get_data(zend_object_iterator *iterator, zval ***data TSRMLS_DC) /* {{{ */
+{
+	zend_generator *generator = (zend_generator *) iterator->data;
+
+	zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+	if (generator->value) {
+		*data = &generator->value;
+	} else {
+		*data = NULL;
+	}
+}
+/* }}} */
+
+static int zend_generator_iterator_get_key(zend_object_iterator *iterator, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
+{
+	zend_generator *generator = (zend_generator *) iterator->data;
+
+	zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+	if (!generator->key) {
+		return HASH_KEY_NON_EXISTANT;
+	}
+
+	if (Z_TYPE_P(generator->key) == IS_LONG) {
+		*int_key = Z_LVAL_P(generator->key);
+		return HASH_KEY_IS_LONG;
+	}
+
+	if (Z_TYPE_P(generator->key) == IS_STRING) {
+		*str_key = estrndup(Z_STRVAL_P(generator->key), Z_STRLEN_P(generator->key));
+		*str_key_len = Z_STRLEN_P(generator->key) + 1;
+		return HASH_KEY_IS_STRING;
+	}
+
+	/* Waiting for Etienne's patch to allow arbitrary zval keys. Until then
+	 * error out on non-int and non-string keys. */
+	zend_error_noreturn(E_ERROR, "Currently only int and string keys can be yielded");
+}
+/* }}} */
+
+static void zend_generator_iterator_move_forward(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
+{
+	zend_generator *generator = (zend_generator *) iterator->data;
+
+	zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+	zend_generator_resume(generator TSRMLS_CC);
+}
+/* }}} */
+
+static void zend_generator_iterator_rewind(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
+{
+	zend_generator *generator = (zend_generator *) iterator->data;
+
+	zend_generator_rewind(generator TSRMLS_CC);
+}
+/* }}} */
+
+static zend_object_iterator_funcs zend_generator_iterator_functions = {
+	zend_generator_iterator_dtor,
+	zend_generator_iterator_valid,
+	zend_generator_iterator_get_data,
+	zend_generator_iterator_get_key,
+	zend_generator_iterator_move_forward,
+	zend_generator_iterator_rewind
+};
+
+zend_object_iterator *zend_generator_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
+{
+	zend_generator_iterator *iterator;
+	zend_generator *generator;
+
+	generator = (zend_generator *) zend_object_store_get_object(object TSRMLS_CC);
+
+	if (!generator->execute_data) {
+		zend_throw_exception(NULL, "Cannot traverse an already closed generator", 0 TSRMLS_CC);
+		return NULL;
+	}
+
+	if (by_ref && !(generator->execute_data->op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+		zend_throw_exception(NULL, "You can only iterate a generator by-reference if it declared that it yields by-reference", 0 TSRMLS_CC);
+		return NULL;
+	}
+
+	iterator = emalloc(sizeof(zend_generator_iterator));
+	iterator->intern.funcs = &zend_generator_iterator_functions;
+	iterator->intern.data = (void *) generator;
+
+	/* We have to keep a reference to the generator object zval around,
+	 * otherwise the generator may be destroyed during iteration. */
+	Z_ADDREF_P(object);
+	iterator->object = object;
+
+	return (zend_object_iterator *) iterator;
+}
+/* }}} */
+
+ZEND_BEGIN_ARG_INFO(arginfo_generator_void, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_generator_send, 0, 0, 1)
+	ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry generator_functions[] = {
+	ZEND_ME(Generator, rewind,   arginfo_generator_void, ZEND_ACC_PUBLIC)
+	ZEND_ME(Generator, valid,    arginfo_generator_void, ZEND_ACC_PUBLIC)
+	ZEND_ME(Generator, current,  arginfo_generator_void, ZEND_ACC_PUBLIC)
+	ZEND_ME(Generator, key,      arginfo_generator_void, ZEND_ACC_PUBLIC)
+	ZEND_ME(Generator, next,     arginfo_generator_void, ZEND_ACC_PUBLIC)
+	ZEND_ME(Generator, send,     arginfo_generator_send, ZEND_ACC_PUBLIC)
+	ZEND_ME(Generator, __wakeup, arginfo_generator_void, ZEND_ACC_PUBLIC)
+	ZEND_FE_END
+};
+
+void zend_register_generator_ce(TSRMLS_D) /* {{{ */
+{
+	zend_class_entry ce;
+
+	INIT_CLASS_ENTRY(ce, "Generator", generator_functions);
+	zend_ce_generator = zend_register_internal_class(&ce TSRMLS_CC);
+	zend_ce_generator->ce_flags |= ZEND_ACC_FINAL_CLASS;
+	zend_ce_generator->create_object = zend_generator_create;
+	zend_ce_generator->serialize = zend_class_serialize_deny;
+	zend_ce_generator->unserialize = zend_class_unserialize_deny;
+
+	/* get_iterator has to be assigned *after* implementing the inferface */
+	zend_class_implements(zend_ce_generator TSRMLS_CC, 1, zend_ce_iterator);
+	zend_ce_generator->get_iterator = zend_generator_get_iterator;
+	zend_ce_generator->iterator_funcs.funcs = &zend_generator_iterator_functions;
+
+	memcpy(&zend_generator_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+	zend_generator_handlers.get_constructor = zend_generator_get_constructor;
+	zend_generator_handlers.clone_obj = zend_objects_store_clone_obj;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ */
diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h
new file mode 100644
index 0000000000000..e47b7ad885f8e
--- /dev/null
+++ b/Zend/zend_generators.h
@@ -0,0 +1,73 @@
+/*
+   +----------------------------------------------------------------------+
+   | Zend Engine                                                          |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.00 of the Zend license,     |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.zend.com/license/2_00.txt.                                |
+   | If you did not receive a copy of the Zend license and are unable to  |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@zend.com so we can mail you a copy immediately.              |
+   +----------------------------------------------------------------------+
+   | Authors: Nikita Popov <nikic@php.net>                                |
+   +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef ZEND_GENERATORS_H
+#define ZEND_GENERATORS_H
+
+BEGIN_EXTERN_C()
+extern ZEND_API zend_class_entry *zend_ce_generator;
+END_EXTERN_C()
+
+typedef struct _zend_generator {
+	zend_object std;
+
+	/* The suspended execution context. */
+	zend_execute_data *execute_data;
+
+	/* If the execution is suspended during a function call there may be
+	 * arguments pushed to the stack, so it has to be backed up. */
+	void *backed_up_stack;
+	size_t backed_up_stack_size;
+
+	/* The original stack top before resuming the generator. This is required
+	 * for proper cleanup during exception handling. */
+	void **original_stack_top;
+
+	/* Current value */
+	zval *value;
+	/* Current key */
+	zval *key;
+	/* Variable to put sent value into */
+	temp_variable *send_target;
+	/* Largest used integer key for auto-incrementing keys */
+	long largest_used_integer_key;
+
+	/* ZEND_GENERATOR_* flags */
+	zend_uchar flags;
+} zend_generator;
+
+static const zend_uchar ZEND_GENERATOR_CURRENTLY_RUNNING = 0x1;
+static const zend_uchar ZEND_GENERATOR_FORCED_CLOSE      = 0x2;
+static const zend_uchar ZEND_GENERATOR_AT_FIRST_YIELD    = 0x4;
+
+void zend_register_generator_ce(TSRMLS_D);
+zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC);
+void zend_generator_close(zend_generator *generator, zend_bool finished_execution TSRMLS_DC);
+void zend_generator_resume(zend_generator *generator TSRMLS_DC);
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ */
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index 32f35fa25250d..c1514c5d783c1 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -68,6 +68,8 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
 %token T_LOGICAL_AND  "and (T_LOGICAL_AND)"
 %right T_PRINT
 %token T_PRINT        "print (T_PRINT)"
+%right T_YIELD
+%token T_YIELD        "yield (T_YIELD)"
 %left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL
 %token T_PLUS_EQUAL   "+= (T_PLUS_EQUAL)"
 %token T_MINUS_EQUAL  "-= (T_MINUS_EQUAL)"
@@ -277,10 +279,10 @@ statement:
 
 unticked_statement:
 		'{' inner_statement_list '}'
-	|	T_IF '(' expr ')' { zend_do_if_cond(&$3, &$4 TSRMLS_CC); } statement { zend_do_if_after_statement(&$4, 1 TSRMLS_CC); } elseif_list else_single { zend_do_if_end(TSRMLS_C); }
-	|	T_IF '(' expr ')' ':' { zend_do_if_cond(&$3, &$4 TSRMLS_CC); } inner_statement_list { zend_do_if_after_statement(&$4, 1 TSRMLS_CC); } new_elseif_list new_else_single T_ENDIF ';' { zend_do_if_end(TSRMLS_C); }
-	|	T_WHILE '(' { $1.u.op.opline_num = get_next_op_number(CG(active_op_array));  } expr  ')' { zend_do_while_cond(&$4, &$5 TSRMLS_CC); } while_statement { zend_do_while_end(&$1, &$5 TSRMLS_CC); }
-	|	T_DO { $1.u.op.opline_num = get_next_op_number(CG(active_op_array));  zend_do_do_while_begin(TSRMLS_C); } statement T_WHILE '(' { $5.u.op.opline_num = get_next_op_number(CG(active_op_array)); } expr ')' ';' { zend_do_do_while_end(&$1, &$5, &$7 TSRMLS_CC); }
+	|	T_IF parenthesis_expr { zend_do_if_cond(&$2, &$1 TSRMLS_CC); } statement { zend_do_if_after_statement(&$1, 1 TSRMLS_CC); } elseif_list else_single { zend_do_if_end(TSRMLS_C); }
+	|	T_IF parenthesis_expr ':' { zend_do_if_cond(&$2, &$1 TSRMLS_CC); } inner_statement_list { zend_do_if_after_statement(&$1, 1 TSRMLS_CC); } new_elseif_list new_else_single T_ENDIF ';' { zend_do_if_end(TSRMLS_C); }
+	|	T_WHILE { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); } parenthesis_expr { zend_do_while_cond(&$3, &$$ TSRMLS_CC); } while_statement { zend_do_while_end(&$1, &$4 TSRMLS_CC); }
+	|	T_DO { $1.u.op.opline_num = get_next_op_number(CG(active_op_array));  zend_do_do_while_begin(TSRMLS_C); } statement T_WHILE { $4.u.op.opline_num = get_next_op_number(CG(active_op_array)); } parenthesis_expr ';' { zend_do_do_while_end(&$1, &$4, &$6 TSRMLS_CC); }
 	|	T_FOR
 			'('
 				for_expr
@@ -290,7 +292,7 @@ unticked_statement:
 				for_expr
 			')' { zend_do_free(&$9 TSRMLS_CC); zend_do_for_before_statement(&$4, &$7 TSRMLS_CC); }
 			for_statement { zend_do_for_end(&$7 TSRMLS_CC); }
-	|	T_SWITCH '(' expr ')'	{ zend_do_switch_cond(&$3 TSRMLS_CC); } switch_case_list { zend_do_switch_end(&$6 TSRMLS_CC); }
+	|	T_SWITCH parenthesis_expr	{ zend_do_switch_cond(&$2 TSRMLS_CC); } switch_case_list { zend_do_switch_end(&$4 TSRMLS_CC); }
 	|	T_BREAK ';'				{ zend_do_brk_cont(ZEND_BRK, NULL TSRMLS_CC); }
 	|	T_BREAK expr ';'		{ zend_do_brk_cont(ZEND_BRK, &$2 TSRMLS_CC); }
 	|	T_CONTINUE ';'			{ zend_do_brk_cont(ZEND_CONT, NULL TSRMLS_CC); }
@@ -298,6 +300,7 @@ unticked_statement:
 	|	T_RETURN ';'						{ zend_do_return(NULL, 0 TSRMLS_CC); }
 	|	T_RETURN expr_without_variable ';'	{ zend_do_return(&$2, 0 TSRMLS_CC); }
 	|	T_RETURN variable ';'				{ zend_do_return(&$2, 1 TSRMLS_CC); }
+	|	yield_expr ';' { $$ = $1; }
 	|	T_GLOBAL global_var_list ';'
 	|	T_STATIC static_var_list ';'
 	|	T_ECHO echo_expr_list ';'
@@ -310,7 +313,7 @@ unticked_statement:
 		foreach_statement { zend_do_foreach_end(&$1, &$4 TSRMLS_CC); }
 	|	T_FOREACH '(' expr_without_variable T_AS
 		{ zend_do_foreach_begin(&$1, &$2, &$3, &$4, 0 TSRMLS_CC); }
-		foreach_variable foreach_optional_arg ')' { zend_check_writable_variable(&$6); zend_do_foreach_cont(&$1, &$2, &$4, &$6, &$7 TSRMLS_CC); }
+		foreach_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$1, &$2, &$4, &$6, &$7 TSRMLS_CC); }
 		foreach_statement { zend_do_foreach_end(&$1, &$4 TSRMLS_CC); }
 	|	T_DECLARE { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(&$1 TSRMLS_CC); }
 	|	';'		/* empty statement */
@@ -365,7 +368,6 @@ class_declaration_statement:
 		unticked_class_declaration_statement	{ DO_TICKS(); }
 ;
 
-
 is_reference:
 		/* empty */	{ $$.op_type = ZEND_RETURN_VAL; }
 	|	'&'			{ $$.op_type = ZEND_RETURN_REF; }
@@ -374,7 +376,8 @@ is_reference:
 
 unticked_function_declaration_statement:
 		function is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$3, 0, $2.op_type, NULL TSRMLS_CC); }
-			'(' parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
+		'(' parameter_list ')'
+		'{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
 ;
 
 unticked_class_declaration_statement:
@@ -489,13 +492,13 @@ while_statement:
 
 elseif_list:
 		/* empty */
-	|	elseif_list T_ELSEIF '(' expr ')' { zend_do_if_cond(&$4, &$5 TSRMLS_CC); } statement { zend_do_if_after_statement(&$5, 0 TSRMLS_CC); }
+	|	elseif_list T_ELSEIF parenthesis_expr { zend_do_if_cond(&$3, &$2 TSRMLS_CC); } statement { zend_do_if_after_statement(&$2, 0 TSRMLS_CC); }
 ;
 
 
 new_elseif_list:
 		/* empty */
-	|	new_elseif_list T_ELSEIF '(' expr ')' ':' { zend_do_if_cond(&$4, &$5 TSRMLS_CC); } inner_statement_list { zend_do_if_after_statement(&$5, 0 TSRMLS_CC); }
+	|	new_elseif_list T_ELSEIF parenthesis_expr ':' { zend_do_if_cond(&$3, &$2 TSRMLS_CC); } inner_statement_list { zend_do_if_after_statement(&$2, 0 TSRMLS_CC); }
 ;
 
 
@@ -538,8 +541,9 @@ optional_class_type:
 
 
 function_call_parameter_list:
-		non_empty_function_call_parameter_list	{ $$ = $1; }
-	|	/* empty */				{ Z_LVAL($$.u.constant) = 0; }
+		'(' ')'	{ Z_LVAL($$.u.constant) = 0; }
+	|	'(' non_empty_function_call_parameter_list ')'	{ $$ = $2; }
+	|	'(' yield_expr ')'	{ Z_LVAL($$.u.constant) = 1; zend_do_pass_param(&$2, ZEND_SEND_VAL, Z_LVAL($$.u.constant) TSRMLS_CC); }
 ;
 
 
@@ -584,8 +588,9 @@ class_statement:
 		variable_modifiers { CG(access_type) = Z_LVAL($1.u.constant); } class_variable_declaration ';'
 	|	class_constant_declaration ';'
 	|	trait_use_statement
-	|	method_modifiers function is_reference T_STRING { zend_do_begin_function_declaration(&$2, &$4, 1, $3.op_type, &$1 TSRMLS_CC); } '('
-			parameter_list ')' method_body { zend_do_abstract_method(&$4, &$1, &$9 TSRMLS_CC); zend_do_end_function_declaration(&$2 TSRMLS_CC); }
+	|	method_modifiers function is_reference T_STRING { zend_do_begin_function_declaration(&$2, &$4, 1, $3.op_type, &$1 TSRMLS_CC); }
+		'(' parameter_list ')'
+		method_body { zend_do_abstract_method(&$4, &$1, &$9 TSRMLS_CC); zend_do_end_function_declaration(&$2 TSRMLS_CC); }
 ;
 
 trait_use_statement:
@@ -778,7 +783,7 @@ expr_without_variable:
 	|	expr '>' expr 					{ zend_do_binary_op(ZEND_IS_SMALLER, &$$, &$3, &$1 TSRMLS_CC); }
 	|	expr T_IS_GREATER_OR_EQUAL expr { zend_do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$3, &$1 TSRMLS_CC); }
 	|	expr T_INSTANCEOF class_name_reference { zend_do_instanceof(&$$, &$1, &$3, 0 TSRMLS_CC); }
-	|	'(' expr ')' 	{ $$ = $2; }
+	|	parenthesis_expr 	{ $$ = $1; }
 	|	new_expr		{ $$ = $1; }
 	|	'(' new_expr ')' { $$ = $2; } instance_call { $$ = $5; }
 	|	expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); }
@@ -801,10 +806,20 @@ expr_without_variable:
 	|	combined_scalar { $$ = $1; }
 	|	'`' backticks_expr '`' { zend_do_shell_exec(&$$, &$2 TSRMLS_CC); }
 	|	T_PRINT expr  { zend_do_print(&$$, &$2 TSRMLS_CC); }
-	|	function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type, 0 TSRMLS_CC); }
-			parameter_list ')' lexical_vars '{' inner_statement_list '}' {  zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $4; }
-	|	T_STATIC function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$2, $3.op_type, 1 TSRMLS_CC); }
-			parameter_list ')' lexical_vars '{' inner_statement_list '}' {  zend_do_end_function_declaration(&$2 TSRMLS_CC); $$ = $5; }
+	|	T_YIELD { zend_do_yield(&$$, NULL, NULL, 0 TSRMLS_CC); }
+	|	function is_reference { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type, 0 TSRMLS_CC); }
+		'(' parameter_list ')' lexical_vars
+		'{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $3; }
+	|	T_STATIC function is_reference { zend_do_begin_lambda_function_declaration(&$$, &$2, $3.op_type, 1 TSRMLS_CC); }
+		'(' parameter_list ')' lexical_vars
+		'{' inner_statement_list '}' { zend_do_end_function_declaration(&$2 TSRMLS_CC); $$ = $4; }
+;
+
+yield_expr:
+		T_YIELD expr_without_variable { zend_do_yield(&$$, &$2, NULL, 0 TSRMLS_CC); }
+	|	T_YIELD variable { zend_do_yield(&$$, &$2, NULL, 1 TSRMLS_CC); }
+	|	T_YIELD expr T_DOUBLE_ARROW expr_without_variable { zend_do_yield(&$$, &$4, &$2, 0 TSRMLS_CC); }
+	|	T_YIELD expr T_DOUBLE_ARROW variable { zend_do_yield(&$$, &$4, &$2, 1 TSRMLS_CC); }
 ;
 
 combined_scalar_offset:
@@ -833,30 +848,22 @@ lexical_var_list:
 ;
 
 function_call:
-		namespace_name '(' { $2.u.op.opline_num = zend_do_begin_function_call(&$1, 1 TSRMLS_CC); }
-				function_call_parameter_list
-				')' { zend_do_end_function_call(&$1, &$$, &$4, 0, $2.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
-	|	T_NAMESPACE T_NS_SEPARATOR namespace_name '(' { $1.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$1.u.constant);  zend_do_build_namespace_name(&$1, &$1, &$3 TSRMLS_CC); $4.u.op.opline_num = zend_do_begin_function_call(&$1, 0 TSRMLS_CC); }
-				function_call_parameter_list
-				')' { zend_do_end_function_call(&$1, &$$, &$6, 0, $4.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
-	|	T_NS_SEPARATOR namespace_name '(' { $3.u.op.opline_num = zend_do_begin_function_call(&$2, 0 TSRMLS_CC); }
-				function_call_parameter_list
-				')' { zend_do_end_function_call(&$2, &$$, &$5, 0, $3.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
-	|	class_name T_PAAMAYIM_NEKUDOTAYIM variable_name '(' { $4.u.op.opline_num = zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
-			function_call_parameter_list
-			')' { zend_do_end_function_call($4.u.op.opline_num?NULL:&$3, &$$, &$6, $4.u.op.opline_num, $4.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
-	|	class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects '(' { zend_do_end_variable_parse(&$3, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
-			function_call_parameter_list
-			')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
-	|	variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_name '(' { zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
-			function_call_parameter_list
-			')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
-	|	variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects '(' { zend_do_end_variable_parse(&$3, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
-			function_call_parameter_list
-			')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
-	|	variable_without_objects  '(' { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); }
-			function_call_parameter_list ')'
-			{ zend_do_end_function_call(&$1, &$$, &$4, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+		namespace_name { $$.u.op.opline_num = zend_do_begin_function_call(&$1, 1 TSRMLS_CC); }
+		function_call_parameter_list { zend_do_end_function_call(&$1, &$$, &$3, 0, $2.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
+	|	T_NAMESPACE T_NS_SEPARATOR namespace_name { $1.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$1.u.constant);  zend_do_build_namespace_name(&$1, &$1, &$3 TSRMLS_CC); $$.u.op.opline_num = zend_do_begin_function_call(&$1, 0 TSRMLS_CC); }
+		function_call_parameter_list { zend_do_end_function_call(&$1, &$$, &$5, 0, $4.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
+	|	T_NS_SEPARATOR namespace_name { $$.u.op.opline_num = zend_do_begin_function_call(&$2, 0 TSRMLS_CC); }
+		function_call_parameter_list { zend_do_end_function_call(&$2, &$$, &$4, 0, $3.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
+	|	class_name T_PAAMAYIM_NEKUDOTAYIM variable_name { $$.u.op.opline_num = zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
+		function_call_parameter_list { zend_do_end_function_call($4.u.op.opline_num?NULL:&$3, &$$, &$5, $4.u.op.opline_num, $4.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+	|	class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { zend_do_end_variable_parse(&$3, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
+		function_call_parameter_list { zend_do_end_function_call(NULL, &$$, &$5, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+	|	variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_name { zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
+		function_call_parameter_list { zend_do_end_function_call(NULL, &$$, &$5, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+	|	variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { zend_do_end_variable_parse(&$3, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
+		function_call_parameter_list { zend_do_end_function_call(NULL, &$$, &$5, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+	|	variable_without_objects { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); }
+		function_call_parameter_list { zend_do_end_function_call(&$1, &$$, &$3, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
 ;
 
 class_name:
@@ -901,7 +908,7 @@ dynamic_class_name_variable_property:
 exit_expr:
 		/* empty */	{ memset(&$$, 0, sizeof(znode)); $$.op_type = IS_UNUSED; }
 	|	'(' ')'		{ memset(&$$, 0, sizeof(znode)); $$.op_type = IS_UNUSED; }
-	|	'(' expr ')'	{ $$ = $2; }
+	|	parenthesis_expr	{ $$ = $1; }
 ;
 
 backticks_expr:
@@ -912,8 +919,8 @@ backticks_expr:
 
 
 ctor_arguments:
-		/* empty */	{ Z_LVAL($$.u.constant)=0; }
-	|	'(' function_call_parameter_list ')'	{ $$ = $2; }
+		/* empty */	{ Z_LVAL($$.u.constant) = 0; }
+	|	function_call_parameter_list 	{ $$ = $1; }
 ;
 
 
@@ -985,6 +992,11 @@ expr:
 	|	expr_without_variable		{ $$ = $1; }
 ;
 
+parenthesis_expr:
+		'(' expr ')'		{ $$ = $2; }
+	|	'(' yield_expr ')'	{ $$ = $2; }
+;
+
 
 r_variable:
 	variable { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); $$ = $1; }
@@ -1024,9 +1036,8 @@ array_method_dereference:
 ;
 
 method:
-		'(' { zend_do_pop_object(&$1 TSRMLS_CC); zend_do_begin_method_call(&$1 TSRMLS_CC); }
-				function_call_parameter_list ')'
-			{ zend_do_end_function_call(&$1, &$$, &$3, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
+		{ zend_do_pop_object(&$$ TSRMLS_CC); zend_do_begin_method_call(&$$ TSRMLS_CC); }
+		function_call_parameter_list { zend_do_end_function_call(&$1, &$$, &$2, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
 ;
 
 method_or_not:
diff --git a/Zend/zend_language_scanner.c b/Zend/zend_language_scanner.c
index b8b4ea95d881b..07ccb5d751a2f 100644
--- a/Zend/zend_language_scanner.c
+++ b/Zend/zend_language_scanner.c
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Sun Aug 19 20:57:55 2012 */
+/* Generated by re2c 0.13.5 on Mon Aug 20 13:34:50 2012 */
 #line 1 "Zend/zend_language_scanner.l"
 /*
    +----------------------------------------------------------------------+
@@ -1099,7 +1099,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 yy3:
 		YYDEBUG(3, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1797 "Zend/zend_language_scanner.l"
+#line 1801 "Zend/zend_language_scanner.l"
 		{
 	if (YYCURSOR > YYLIMIT) {
 		return 0;
@@ -1177,7 +1177,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 yy6:
 		YYDEBUG(6, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1785 "Zend/zend_language_scanner.l"
+#line 1789 "Zend/zend_language_scanner.l"
 		{
 	if (CG(short_tags)) {
 		zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1196,7 +1196,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		if ((yych = *YYCURSOR) == '=') goto yy43;
 		YYDEBUG(8, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1762 "Zend/zend_language_scanner.l"
+#line 1766 "Zend/zend_language_scanner.l"
 		{
 	if (CG(asp_tags)) {
 		zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1394,7 +1394,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(38, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1722 "Zend/zend_language_scanner.l"
+#line 1726 "Zend/zend_language_scanner.l"
 		{
 	YYCTYPE *bracket = (YYCTYPE*)zend_memrchr(yytext, '<', yyleng - (sizeof("script language=php>") - 1));
 
@@ -1438,7 +1438,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(44, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1740 "Zend/zend_language_scanner.l"
+#line 1744 "Zend/zend_language_scanner.l"
 		{
 	if (CG(asp_tags)) {
 		zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1456,7 +1456,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(46, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1753 "Zend/zend_language_scanner.l"
+#line 1757 "Zend/zend_language_scanner.l"
 		{
 	zendlval->value.str.val = yytext; /* no copying - intentional */
 	zendlval->value.str.len = yyleng;
@@ -1491,7 +1491,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 yy51:
 		YYDEBUG(51, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1775 "Zend/zend_language_scanner.l"
+#line 1779 "Zend/zend_language_scanner.l"
 		{
 	zendlval->value.str.val = yytext; /* no copying - intentional */
 	zendlval->value.str.len = yyleng;
@@ -1571,7 +1571,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 yy56:
 		YYDEBUG(56, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2248 "Zend/zend_language_scanner.l"
+#line 2252 "Zend/zend_language_scanner.l"
 		{
 	if (YYCURSOR > YYLIMIT) {
 		return 0;
@@ -1623,7 +1623,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(59, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2192 "Zend/zend_language_scanner.l"
+#line 2196 "Zend/zend_language_scanner.l"
 		{
 	BEGIN(ST_IN_SCRIPTING);
 	return '`';
@@ -1638,7 +1638,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(62, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2179 "Zend/zend_language_scanner.l"
+#line 2183 "Zend/zend_language_scanner.l"
 		{
 	zendlval->value.lval = (long) '{';
 	yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
@@ -1661,7 +1661,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 yy65:
 		YYDEBUG(65, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1879 "Zend/zend_language_scanner.l"
+#line 1883 "Zend/zend_language_scanner.l"
 		{
 	zend_copy_value(zendlval, (yytext+1), (yyleng-1));
 	zendlval->type = IS_STRING;
@@ -1673,7 +1673,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(67, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1455 "Zend/zend_language_scanner.l"
+#line 1459 "Zend/zend_language_scanner.l"
 		{
 	yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
 	return T_DOLLAR_OPEN_CURLY_BRACES;
@@ -1692,7 +1692,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(71, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1871 "Zend/zend_language_scanner.l"
+#line 1875 "Zend/zend_language_scanner.l"
 		{
 	yyless(yyleng - 1);
 	yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -1718,7 +1718,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(74, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1861 "Zend/zend_language_scanner.l"
+#line 1865 "Zend/zend_language_scanner.l"
 		{
 	yyless(yyleng - 3);
 	yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -1794,7 +1794,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 yy78:
 		YYDEBUG(78, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2198 "Zend/zend_language_scanner.l"
+#line 2202 "Zend/zend_language_scanner.l"
 		{
 	if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) {
 		YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1;
@@ -1854,7 +1854,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(81, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2187 "Zend/zend_language_scanner.l"
+#line 2191 "Zend/zend_language_scanner.l"
 		{
 	BEGIN(ST_IN_SCRIPTING);
 	return '"';
@@ -1869,7 +1869,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(84, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2179 "Zend/zend_language_scanner.l"
+#line 2183 "Zend/zend_language_scanner.l"
 		{
 	zendlval->value.lval = (long) '{';
 	yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
@@ -1892,7 +1892,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 yy87:
 		YYDEBUG(87, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1879 "Zend/zend_language_scanner.l"
+#line 1883 "Zend/zend_language_scanner.l"
 		{
 	zend_copy_value(zendlval, (yytext+1), (yyleng-1));
 	zendlval->type = IS_STRING;
@@ -1904,7 +1904,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(89, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1455 "Zend/zend_language_scanner.l"
+#line 1459 "Zend/zend_language_scanner.l"
 		{
 	yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
 	return T_DOLLAR_OPEN_CURLY_BRACES;
@@ -1923,7 +1923,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(93, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1871 "Zend/zend_language_scanner.l"
+#line 1875 "Zend/zend_language_scanner.l"
 		{
 	yyless(yyleng - 1);
 	yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -1949,7 +1949,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(96, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1861 "Zend/zend_language_scanner.l"
+#line 1865 "Zend/zend_language_scanner.l"
 		{
 	yyless(yyleng - 3);
 	yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -1968,7 +1968,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	++YYCURSOR;
 	YYDEBUG(100, *YYCURSOR);
 	yyleng = YYCURSOR - SCNG(yy_text);
-#line 2165 "Zend/zend_language_scanner.l"
+#line 2169 "Zend/zend_language_scanner.l"
 	{
 	zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack));
 
@@ -2043,7 +2043,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 yy104:
 		YYDEBUG(104, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2290 "Zend/zend_language_scanner.l"
+#line 2294 "Zend/zend_language_scanner.l"
 		{
 	int newline = 0;
 
@@ -2131,7 +2131,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(108, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2179 "Zend/zend_language_scanner.l"
+#line 2183 "Zend/zend_language_scanner.l"
 		{
 	zendlval->value.lval = (long) '{';
 	yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
@@ -2154,7 +2154,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 yy111:
 		YYDEBUG(111, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1879 "Zend/zend_language_scanner.l"
+#line 1883 "Zend/zend_language_scanner.l"
 		{
 	zend_copy_value(zendlval, (yytext+1), (yyleng-1));
 	zendlval->type = IS_STRING;
@@ -2166,7 +2166,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(113, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1455 "Zend/zend_language_scanner.l"
+#line 1459 "Zend/zend_language_scanner.l"
 		{
 	yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
 	return T_DOLLAR_OPEN_CURLY_BRACES;
@@ -2185,7 +2185,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(117, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1871 "Zend/zend_language_scanner.l"
+#line 1875 "Zend/zend_language_scanner.l"
 		{
 	yyless(yyleng - 1);
 	yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -2211,7 +2211,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		++YYCURSOR;
 		YYDEBUG(120, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1861 "Zend/zend_language_scanner.l"
+#line 1865 "Zend/zend_language_scanner.l"
 		{
 	yyless(yyleng - 3);
 	yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -2291,32 +2291,32 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		case 0x1C:
 		case 0x1D:
 		case 0x1E:
-		case 0x1F:	goto yy183;
+		case 0x1F:	goto yy184;
 		case '\t':
 		case '\n':
 		case '\r':
-		case ' ':	goto yy139;
-		case '!':	goto yy152;
-		case '"':	goto yy179;
-		case '#':	goto yy175;
-		case '$':	goto yy164;
-		case '%':	goto yy158;
-		case '&':	goto yy159;
-		case '\'':	goto yy177;
-		case '(':	goto yy146;
+		case ' ':	goto yy140;
+		case '!':	goto yy153;
+		case '"':	goto yy180;
+		case '#':	goto yy176;
+		case '$':	goto yy165;
+		case '%':	goto yy159;
+		case '&':	goto yy160;
+		case '\'':	goto yy178;
+		case '(':	goto yy147;
 		case ')':
 		case ',':
 		case ';':
 		case '@':
 		case '[':
 		case ']':
-		case '~':	goto yy165;
-		case '*':	goto yy155;
-		case '+':	goto yy151;
-		case '-':	goto yy137;
-		case '.':	goto yy157;
-		case '/':	goto yy156;
-		case '0':	goto yy171;
+		case '~':	goto yy166;
+		case '*':	goto yy156;
+		case '+':	goto yy152;
+		case '-':	goto yy138;
+		case '.':	goto yy158;
+		case '/':	goto yy157;
+		case '0':	goto yy172;
 		case '1':
 		case '2':
 		case '3':
@@ -2325,16 +2325,16 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		case '6':
 		case '7':
 		case '8':
-		case '9':	goto yy173;
-		case ':':	goto yy141;
-		case '<':	goto yy153;
-		case '=':	goto yy149;
-		case '>':	goto yy154;
-		case '?':	goto yy166;
+		case '9':	goto yy174;
+		case ':':	goto yy142;
+		case '<':	goto yy154;
+		case '=':	goto yy150;
+		case '>':	goto yy155;
+		case '?':	goto yy167;
 		case 'A':
-		case 'a':	goto yy132;
+		case 'a':	goto yy133;
 		case 'B':
-		case 'b':	goto yy134;
+		case 'b':	goto yy135;
 		case 'C':
 		case 'c':	goto yy127;
 		case 'D':
@@ -2344,39 +2344,41 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		case 'F':
 		case 'f':	goto yy126;
 		case 'G':
-		case 'g':	goto yy135;
+		case 'g':	goto yy136;
 		case 'I':
-		case 'i':	goto yy130;
+		case 'i':	goto yy131;
 		case 'L':
-		case 'l':	goto yy150;
+		case 'l':	goto yy151;
 		case 'N':
-		case 'n':	goto yy144;
+		case 'n':	goto yy145;
 		case 'O':
-		case 'o':	goto yy162;
+		case 'o':	goto yy163;
 		case 'P':
-		case 'p':	goto yy136;
+		case 'p':	goto yy137;
 		case 'R':
 		case 'r':	goto yy128;
 		case 'S':
-		case 's':	goto yy133;
+		case 's':	goto yy134;
 		case 'T':
-		case 't':	goto yy129;
+		case 't':	goto yy130;
 		case 'U':
-		case 'u':	goto yy147;
+		case 'u':	goto yy148;
 		case 'V':
-		case 'v':	goto yy145;
+		case 'v':	goto yy146;
 		case 'W':
-		case 'w':	goto yy131;
+		case 'w':	goto yy132;
 		case 'X':
-		case 'x':	goto yy163;
-		case '\\':	goto yy142;
-		case '^':	goto yy161;
-		case '_':	goto yy148;
-		case '`':	goto yy181;
-		case '{':	goto yy167;
-		case '|':	goto yy160;
-		case '}':	goto yy169;
-		default:	goto yy174;
+		case 'x':	goto yy164;
+		case 'Y':
+		case 'y':	goto yy129;
+		case '\\':	goto yy143;
+		case '^':	goto yy162;
+		case '_':	goto yy149;
+		case '`':	goto yy182;
+		case '{':	goto yy168;
+		case '|':	goto yy161;
+		case '}':	goto yy170;
+		default:	goto yy175;
 		}
 yy123:
 		YYDEBUG(123, *YYCURSOR);
@@ -2384,49 +2386,49 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		YYDEBUG(-1, yych);
 		switch ((yych = *YYCURSOR)) {
 		case 'C':
-		case 'c':	goto yy729;
+		case 'c':	goto yy735;
 		case 'L':
-		case 'l':	goto yy730;
+		case 'l':	goto yy736;
 		case 'M':
-		case 'm':	goto yy731;
+		case 'm':	goto yy737;
 		case 'N':
-		case 'n':	goto yy732;
+		case 'n':	goto yy738;
 		case 'V':
-		case 'v':	goto yy733;
+		case 'v':	goto yy739;
 		case 'X':
-		case 'x':	goto yy734;
-		default:	goto yy186;
+		case 'x':	goto yy740;
+		default:	goto yy187;
 		}
 yy124:
 		YYDEBUG(124, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1902 "Zend/zend_language_scanner.l"
+#line 1906 "Zend/zend_language_scanner.l"
 		{
 	zend_copy_value(zendlval, yytext, yyleng);
 	zendlval->type = IS_STRING;
 	return T_STRING;
 }
-#line 2410 "Zend/zend_language_scanner.c"
+#line 2412 "Zend/zend_language_scanner.c"
 yy125:
 		YYDEBUG(125, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'O') {
 			if (yych <= 'H') {
-				if (yych == 'E') goto yy711;
-				goto yy186;
+				if (yych == 'E') goto yy717;
+				goto yy187;
 			} else {
-				if (yych <= 'I') goto yy712;
-				if (yych <= 'N') goto yy186;
-				goto yy713;
+				if (yych <= 'I') goto yy718;
+				if (yych <= 'N') goto yy187;
+				goto yy719;
 			}
 		} else {
 			if (yych <= 'h') {
-				if (yych == 'e') goto yy711;
-				goto yy186;
+				if (yych == 'e') goto yy717;
+				goto yy187;
 			} else {
-				if (yych <= 'i') goto yy712;
-				if (yych == 'o') goto yy713;
-				goto yy186;
+				if (yych <= 'i') goto yy718;
+				if (yych == 'o') goto yy719;
+				goto yy187;
 			}
 		}
 yy126:
@@ -2434,21 +2436,21 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		yych = *++YYCURSOR;
 		if (yych <= 'U') {
 			if (yych <= 'N') {
-				if (yych == 'I') goto yy687;
-				goto yy186;
+				if (yych == 'I') goto yy693;
+				goto yy187;
 			} else {
-				if (yych <= 'O') goto yy688;
-				if (yych <= 'T') goto yy186;
-				goto yy689;
+				if (yych <= 'O') goto yy694;
+				if (yych <= 'T') goto yy187;
+				goto yy695;
 			}
 		} else {
 			if (yych <= 'n') {
-				if (yych == 'i') goto yy687;
-				goto yy186;
+				if (yych == 'i') goto yy693;
+				goto yy187;
 			} else {
-				if (yych <= 'o') goto yy688;
-				if (yych == 'u') goto yy689;
-				goto yy186;
+				if (yych <= 'o') goto yy694;
+				if (yych == 'u') goto yy695;
+				goto yy187;
 			}
 		}
 yy127:
@@ -2456,196 +2458,202 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		yych = *++YYCURSOR;
 		if (yych <= 'O') {
 			if (yych <= 'K') {
-				if (yych == 'A') goto yy652;
-				goto yy186;
+				if (yych == 'A') goto yy658;
+				goto yy187;
 			} else {
-				if (yych <= 'L') goto yy653;
-				if (yych <= 'N') goto yy186;
-				goto yy654;
+				if (yych <= 'L') goto yy659;
+				if (yych <= 'N') goto yy187;
+				goto yy660;
 			}
 		} else {
 			if (yych <= 'k') {
-				if (yych == 'a') goto yy652;
-				goto yy186;
+				if (yych == 'a') goto yy658;
+				goto yy187;
 			} else {
-				if (yych <= 'l') goto yy653;
-				if (yych == 'o') goto yy654;
-				goto yy186;
+				if (yych <= 'l') goto yy659;
+				if (yych == 'o') goto yy660;
+				goto yy187;
 			}
 		}
 yy128:
 		YYDEBUG(128, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy634;
-		if (yych == 'e') goto yy634;
-		goto yy186;
+		if (yych == 'E') goto yy640;
+		if (yych == 'e') goto yy640;
+		goto yy187;
 yy129:
 		YYDEBUG(129, *YYCURSOR);
 		yych = *++YYCURSOR;
+		if (yych == 'I') goto yy635;
+		if (yych == 'i') goto yy635;
+		goto yy187;
+yy130:
+		YYDEBUG(130, *YYCURSOR);
+		yych = *++YYCURSOR;
 		if (yych <= 'R') {
-			if (yych == 'H') goto yy622;
-			if (yych <= 'Q') goto yy186;
-			goto yy623;
+			if (yych == 'H') goto yy623;
+			if (yych <= 'Q') goto yy187;
+			goto yy624;
 		} else {
 			if (yych <= 'h') {
-				if (yych <= 'g') goto yy186;
-				goto yy622;
+				if (yych <= 'g') goto yy187;
+				goto yy623;
 			} else {
-				if (yych == 'r') goto yy623;
-				goto yy186;
+				if (yych == 'r') goto yy624;
+				goto yy187;
 			}
 		}
-yy130:
-		YYDEBUG(130, *YYCURSOR);
+yy131:
+		YYDEBUG(131, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'S') {
 			if (yych <= 'L') {
-				if (yych == 'F') goto yy569;
-				goto yy186;
+				if (yych == 'F') goto yy570;
+				goto yy187;
 			} else {
-				if (yych <= 'M') goto yy571;
-				if (yych <= 'N') goto yy572;
-				if (yych <= 'R') goto yy186;
-				goto yy573;
+				if (yych <= 'M') goto yy572;
+				if (yych <= 'N') goto yy573;
+				if (yych <= 'R') goto yy187;
+				goto yy574;
 			}
 		} else {
 			if (yych <= 'm') {
-				if (yych == 'f') goto yy569;
-				if (yych <= 'l') goto yy186;
-				goto yy571;
+				if (yych == 'f') goto yy570;
+				if (yych <= 'l') goto yy187;
+				goto yy572;
 			} else {
-				if (yych <= 'n') goto yy572;
-				if (yych == 's') goto yy573;
-				goto yy186;
+				if (yych <= 'n') goto yy573;
+				if (yych == 's') goto yy574;
+				goto yy187;
 			}
 		}
-yy131:
-		YYDEBUG(131, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'H') goto yy564;
-		if (yych == 'h') goto yy564;
-		goto yy186;
 yy132:
 		YYDEBUG(132, *YYCURSOR);
 		yych = *++YYCURSOR;
+		if (yych == 'H') goto yy565;
+		if (yych == 'h') goto yy565;
+		goto yy187;
+yy133:
+		YYDEBUG(133, *YYCURSOR);
+		yych = *++YYCURSOR;
 		if (yych <= 'S') {
 			if (yych <= 'M') {
-				if (yych == 'B') goto yy546;
-				goto yy186;
+				if (yych == 'B') goto yy547;
+				goto yy187;
 			} else {
-				if (yych <= 'N') goto yy547;
-				if (yych <= 'Q') goto yy186;
-				if (yych <= 'R') goto yy548;
-				goto yy549;
+				if (yych <= 'N') goto yy548;
+				if (yych <= 'Q') goto yy187;
+				if (yych <= 'R') goto yy549;
+				goto yy550;
 			}
 		} else {
 			if (yych <= 'n') {
-				if (yych == 'b') goto yy546;
-				if (yych <= 'm') goto yy186;
-				goto yy547;
+				if (yych == 'b') goto yy547;
+				if (yych <= 'm') goto yy187;
+				goto yy548;
 			} else {
-				if (yych <= 'q') goto yy186;
-				if (yych <= 'r') goto yy548;
-				if (yych <= 's') goto yy549;
-				goto yy186;
+				if (yych <= 'q') goto yy187;
+				if (yych <= 'r') goto yy549;
+				if (yych <= 's') goto yy550;
+				goto yy187;
 			}
 		}
-yy133:
-		YYDEBUG(133, *YYCURSOR);
+yy134:
+		YYDEBUG(134, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'W') {
-			if (yych == 'T') goto yy534;
-			if (yych <= 'V') goto yy186;
-			goto yy535;
+			if (yych == 'T') goto yy535;
+			if (yych <= 'V') goto yy187;
+			goto yy536;
 		} else {
 			if (yych <= 't') {
-				if (yych <= 's') goto yy186;
-				goto yy534;
+				if (yych <= 's') goto yy187;
+				goto yy535;
 			} else {
-				if (yych == 'w') goto yy535;
-				goto yy186;
+				if (yych == 'w') goto yy536;
+				goto yy187;
 			}
 		}
-yy134:
-		YYDEBUG(134, *YYCURSOR);
+yy135:
+		YYDEBUG(135, *YYCURSOR);
 		yyaccept = 0;
 		yych = *(YYMARKER = ++YYCURSOR);
 		if (yych <= ';') {
 			if (yych <= '"') {
-				if (yych <= '!') goto yy186;
-				goto yy526;
+				if (yych <= '!') goto yy187;
+				goto yy527;
 			} else {
-				if (yych == '\'') goto yy527;
-				goto yy186;
+				if (yych == '\'') goto yy528;
+				goto yy187;
 			}
 		} else {
 			if (yych <= 'R') {
-				if (yych <= '<') goto yy525;
-				if (yych <= 'Q') goto yy186;
-				goto yy528;
+				if (yych <= '<') goto yy526;
+				if (yych <= 'Q') goto yy187;
+				goto yy529;
 			} else {
-				if (yych == 'r') goto yy528;
-				goto yy186;
+				if (yych == 'r') goto yy529;
+				goto yy187;
 			}
 		}
-yy135:
-		YYDEBUG(135, *YYCURSOR);
+yy136:
+		YYDEBUG(136, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'O') {
-			if (yych == 'L') goto yy515;
-			if (yych <= 'N') goto yy186;
-			goto yy516;
+			if (yych == 'L') goto yy516;
+			if (yych <= 'N') goto yy187;
+			goto yy517;
 		} else {
 			if (yych <= 'l') {
-				if (yych <= 'k') goto yy186;
-				goto yy515;
+				if (yych <= 'k') goto yy187;
+				goto yy516;
 			} else {
-				if (yych == 'o') goto yy516;
-				goto yy186;
+				if (yych == 'o') goto yy517;
+				goto yy187;
 			}
 		}
-yy136:
-		YYDEBUG(136, *YYCURSOR);
+yy137:
+		YYDEBUG(137, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'U') {
-			if (yych == 'R') goto yy491;
-			if (yych <= 'T') goto yy186;
-			goto yy492;
+			if (yych == 'R') goto yy492;
+			if (yych <= 'T') goto yy187;
+			goto yy493;
 		} else {
 			if (yych <= 'r') {
-				if (yych <= 'q') goto yy186;
-				goto yy491;
+				if (yych <= 'q') goto yy187;
+				goto yy492;
 			} else {
-				if (yych == 'u') goto yy492;
-				goto yy186;
+				if (yych == 'u') goto yy493;
+				goto yy187;
 			}
 		}
-yy137:
-		YYDEBUG(137, *YYCURSOR);
+yy138:
+		YYDEBUG(138, *YYCURSOR);
 		++YYCURSOR;
 		if ((yych = *YYCURSOR) <= '<') {
-			if (yych == '-') goto yy487;
+			if (yych == '-') goto yy488;
 		} else {
-			if (yych <= '=') goto yy485;
-			if (yych <= '>') goto yy489;
+			if (yych <= '=') goto yy486;
+			if (yych <= '>') goto yy490;
 		}
-yy138:
-		YYDEBUG(138, *YYCURSOR);
+yy139:
+		YYDEBUG(139, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1444 "Zend/zend_language_scanner.l"
+#line 1448 "Zend/zend_language_scanner.l"
 		{
 	return yytext[0];
 }
-#line 2640 "Zend/zend_language_scanner.c"
-yy139:
-		YYDEBUG(139, *YYCURSOR);
-		++YYCURSOR;
-		yych = *YYCURSOR;
-		goto yy484;
+#line 2648 "Zend/zend_language_scanner.c"
 yy140:
 		YYDEBUG(140, *YYCURSOR);
+		++YYCURSOR;
+		yych = *YYCURSOR;
+		goto yy485;
+yy141:
+		YYDEBUG(141, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1175 "Zend/zend_language_scanner.l"
+#line 1179 "Zend/zend_language_scanner.l"
 		{
 	zendlval->value.str.val = yytext; /* no copying - intentional */
 	zendlval->value.str.len = yyleng;
@@ -2653,261 +2661,261 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	HANDLE_NEWLINES(yytext, yyleng);
 	return T_WHITESPACE;
 }
-#line 2657 "Zend/zend_language_scanner.c"
-yy141:
-		YYDEBUG(141, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == ':') goto yy481;
-		goto yy138;
+#line 2665 "Zend/zend_language_scanner.c"
 yy142:
 		YYDEBUG(142, *YYCURSOR);
-		++YYCURSOR;
+		yych = *++YYCURSOR;
+		if (yych == ':') goto yy482;
+		goto yy139;
+yy143:
 		YYDEBUG(143, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(144, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1204 "Zend/zend_language_scanner.l"
+#line 1208 "Zend/zend_language_scanner.l"
 		{
 	return T_NS_SEPARATOR;
 }
-#line 2672 "Zend/zend_language_scanner.c"
-yy144:
-		YYDEBUG(144, *YYCURSOR);
+#line 2680 "Zend/zend_language_scanner.c"
+yy145:
+		YYDEBUG(145, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'E') {
-			if (yych == 'A') goto yy469;
-			if (yych <= 'D') goto yy186;
-			goto yy470;
+			if (yych == 'A') goto yy470;
+			if (yych <= 'D') goto yy187;
+			goto yy471;
 		} else {
 			if (yych <= 'a') {
-				if (yych <= '`') goto yy186;
-				goto yy469;
+				if (yych <= '`') goto yy187;
+				goto yy470;
 			} else {
-				if (yych == 'e') goto yy470;
-				goto yy186;
+				if (yych == 'e') goto yy471;
+				goto yy187;
 			}
 		}
-yy145:
-		YYDEBUG(145, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy466;
-		if (yych == 'a') goto yy466;
-		goto yy186;
 yy146:
 		YYDEBUG(146, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'A') goto yy467;
+		if (yych == 'a') goto yy467;
+		goto yy187;
+yy147:
+		YYDEBUG(147, *YYCURSOR);
 		yyaccept = 1;
 		yych = *(YYMARKER = ++YYCURSOR);
 		if (yych <= 'S') {
 			if (yych <= 'D') {
 				if (yych <= ' ') {
-					if (yych == '\t') goto yy391;
-					if (yych <= 0x1F) goto yy138;
-					goto yy391;
+					if (yych == '\t') goto yy392;
+					if (yych <= 0x1F) goto yy139;
+					goto yy392;
 				} else {
-					if (yych <= '@') goto yy138;
-					if (yych == 'C') goto yy138;
-					goto yy391;
+					if (yych <= '@') goto yy139;
+					if (yych == 'C') goto yy139;
+					goto yy392;
 				}
 			} else {
 				if (yych <= 'I') {
-					if (yych == 'F') goto yy391;
-					if (yych <= 'H') goto yy138;
-					goto yy391;
+					if (yych == 'F') goto yy392;
+					if (yych <= 'H') goto yy139;
+					goto yy392;
 				} else {
-					if (yych == 'O') goto yy391;
-					if (yych <= 'Q') goto yy138;
-					goto yy391;
+					if (yych == 'O') goto yy392;
+					if (yych <= 'Q') goto yy139;
+					goto yy392;
 				}
 			}
 		} else {
 			if (yych <= 'f') {
 				if (yych <= 'b') {
-					if (yych == 'U') goto yy391;
-					if (yych <= '`') goto yy138;
-					goto yy391;
+					if (yych == 'U') goto yy392;
+					if (yych <= '`') goto yy139;
+					goto yy392;
 				} else {
-					if (yych == 'd') goto yy391;
-					if (yych <= 'e') goto yy138;
-					goto yy391;
+					if (yych == 'd') goto yy392;
+					if (yych <= 'e') goto yy139;
+					goto yy392;
 				}
 			} else {
 				if (yych <= 'o') {
-					if (yych == 'i') goto yy391;
-					if (yych <= 'n') goto yy138;
-					goto yy391;
+					if (yych == 'i') goto yy392;
+					if (yych <= 'n') goto yy139;
+					goto yy392;
 				} else {
 					if (yych <= 's') {
-						if (yych <= 'q') goto yy138;
-						goto yy391;
+						if (yych <= 'q') goto yy139;
+						goto yy392;
 					} else {
-						if (yych == 'u') goto yy391;
-						goto yy138;
+						if (yych == 'u') goto yy392;
+						goto yy139;
 					}
 				}
 			}
 		}
-yy147:
-		YYDEBUG(147, *YYCURSOR);
+yy148:
+		YYDEBUG(148, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'S') {
-			if (yych == 'N') goto yy382;
-			if (yych <= 'R') goto yy186;
-			goto yy383;
+			if (yych == 'N') goto yy383;
+			if (yych <= 'R') goto yy187;
+			goto yy384;
 		} else {
 			if (yych <= 'n') {
-				if (yych <= 'm') goto yy186;
-				goto yy382;
+				if (yych <= 'm') goto yy187;
+				goto yy383;
 			} else {
-				if (yych == 's') goto yy383;
-				goto yy186;
+				if (yych == 's') goto yy384;
+				goto yy187;
 			}
 		}
-yy148:
-		YYDEBUG(148, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == '_') goto yy300;
-		goto yy186;
 yy149:
 		YYDEBUG(149, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych <= '<') goto yy138;
-		if (yych <= '=') goto yy294;
-		if (yych <= '>') goto yy296;
-		goto yy138;
+		if (yych == '_') goto yy301;
+		goto yy187;
 yy150:
 		YYDEBUG(150, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy290;
-		if (yych == 'i') goto yy290;
-		goto yy186;
+		if (yych <= '<') goto yy139;
+		if (yych <= '=') goto yy295;
+		if (yych <= '>') goto yy297;
+		goto yy139;
 yy151:
 		YYDEBUG(151, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == '+') goto yy288;
-		if (yych == '=') goto yy286;
-		goto yy138;
+		if (yych == 'I') goto yy291;
+		if (yych == 'i') goto yy291;
+		goto yy187;
 yy152:
 		YYDEBUG(152, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == '=') goto yy283;
-		goto yy138;
+		if (yych == '+') goto yy289;
+		if (yych == '=') goto yy287;
+		goto yy139;
 yy153:
 		YYDEBUG(153, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == '=') goto yy284;
+		goto yy139;
+yy154:
+		YYDEBUG(154, *YYCURSOR);
 		yyaccept = 1;
 		yych = *(YYMARKER = ++YYCURSOR);
 		if (yych <= ';') {
-			if (yych == '/') goto yy255;
-			goto yy138;
+			if (yych == '/') goto yy256;
+			goto yy139;
 		} else {
-			if (yych <= '<') goto yy253;
-			if (yych <= '=') goto yy256;
-			if (yych <= '>') goto yy258;
-			goto yy138;
+			if (yych <= '<') goto yy254;
+			if (yych <= '=') goto yy257;
+			if (yych <= '>') goto yy259;
+			goto yy139;
 		}
-yy154:
-		YYDEBUG(154, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych <= '<') goto yy138;
-		if (yych <= '=') goto yy249;
-		if (yych <= '>') goto yy247;
-		goto yy138;
 yy155:
 		YYDEBUG(155, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == '=') goto yy245;
-		goto yy138;
+		if (yych <= '<') goto yy139;
+		if (yych <= '=') goto yy250;
+		if (yych <= '>') goto yy248;
+		goto yy139;
 yy156:
 		YYDEBUG(156, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych <= '.') {
-			if (yych == '*') goto yy237;
-			goto yy138;
-		} else {
-			if (yych <= '/') goto yy239;
-			if (yych == '=') goto yy240;
-			goto yy138;
-		}
+		if (yych == '=') goto yy246;
+		goto yy139;
 yy157:
 		YYDEBUG(157, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych <= '/') goto yy138;
-		if (yych <= '9') goto yy233;
-		if (yych == '=') goto yy235;
-		goto yy138;
+		if (yych <= '.') {
+			if (yych == '*') goto yy238;
+			goto yy139;
+		} else {
+			if (yych <= '/') goto yy240;
+			if (yych == '=') goto yy241;
+			goto yy139;
+		}
 yy158:
 		YYDEBUG(158, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych <= '<') goto yy138;
-		if (yych <= '=') goto yy229;
-		if (yych <= '>') goto yy227;
-		goto yy138;
+		if (yych <= '/') goto yy139;
+		if (yych <= '9') goto yy234;
+		if (yych == '=') goto yy236;
+		goto yy139;
 yy159:
 		YYDEBUG(159, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == '&') goto yy223;
-		if (yych == '=') goto yy225;
-		goto yy138;
+		if (yych <= '<') goto yy139;
+		if (yych <= '=') goto yy230;
+		if (yych <= '>') goto yy228;
+		goto yy139;
 yy160:
 		YYDEBUG(160, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == '=') goto yy221;
-		if (yych == '|') goto yy219;
-		goto yy138;
+		if (yych == '&') goto yy224;
+		if (yych == '=') goto yy226;
+		goto yy139;
 yy161:
 		YYDEBUG(161, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == '=') goto yy217;
-		goto yy138;
+		if (yych == '=') goto yy222;
+		if (yych == '|') goto yy220;
+		goto yy139;
 yy162:
 		YYDEBUG(162, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy215;
-		if (yych == 'r') goto yy215;
-		goto yy186;
+		if (yych == '=') goto yy218;
+		goto yy139;
 yy163:
 		YYDEBUG(163, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy212;
-		if (yych == 'o') goto yy212;
-		goto yy186;
+		if (yych == 'R') goto yy216;
+		if (yych == 'r') goto yy216;
+		goto yy187;
 yy164:
 		YYDEBUG(164, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych <= '_') {
-			if (yych <= '@') goto yy138;
-			if (yych <= 'Z') goto yy209;
-			if (yych <= '^') goto yy138;
-			goto yy209;
-		} else {
-			if (yych <= '`') goto yy138;
-			if (yych <= 'z') goto yy209;
-			if (yych <= '~') goto yy138;
-			goto yy209;
-		}
+		if (yych == 'O') goto yy213;
+		if (yych == 'o') goto yy213;
+		goto yy187;
 yy165:
 		YYDEBUG(165, *YYCURSOR);
 		yych = *++YYCURSOR;
-		goto yy138;
+		if (yych <= '_') {
+			if (yych <= '@') goto yy139;
+			if (yych <= 'Z') goto yy210;
+			if (yych <= '^') goto yy139;
+			goto yy210;
+		} else {
+			if (yych <= '`') goto yy139;
+			if (yych <= 'z') goto yy210;
+			if (yych <= '~') goto yy139;
+			goto yy210;
+		}
 yy166:
 		YYDEBUG(166, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == '>') goto yy205;
-		goto yy138;
+		goto yy139;
 yy167:
 		YYDEBUG(167, *YYCURSOR);
-		++YYCURSOR;
+		yych = *++YYCURSOR;
+		if (yych == '>') goto yy206;
+		goto yy139;
+yy168:
 		YYDEBUG(168, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(169, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1449 "Zend/zend_language_scanner.l"
+#line 1453 "Zend/zend_language_scanner.l"
 		{
 	yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
 	return '{';
 }
-#line 2905 "Zend/zend_language_scanner.c"
-yy169:
-		YYDEBUG(169, *YYCURSOR);
-		++YYCURSOR;
+#line 2913 "Zend/zend_language_scanner.c"
+yy170:
 		YYDEBUG(170, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(171, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1461 "Zend/zend_language_scanner.l"
+#line 1465 "Zend/zend_language_scanner.l"
 		{
 	RESET_DOC_COMMENT();
 	if (!zend_stack_is_empty(&SCNG(state_stack))) {
@@ -2915,35 +2923,35 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	}
 	return '}';
 }
-#line 2919 "Zend/zend_language_scanner.c"
-yy171:
-		YYDEBUG(171, *YYCURSOR);
+#line 2927 "Zend/zend_language_scanner.c"
+yy172:
+		YYDEBUG(172, *YYCURSOR);
 		yyaccept = 2;
 		yych = *(YYMARKER = ++YYCURSOR);
 		if (yych <= 'E') {
 			if (yych <= '9') {
-				if (yych == '.') goto yy187;
-				if (yych >= '0') goto yy190;
+				if (yych == '.') goto yy188;
+				if (yych >= '0') goto yy191;
 			} else {
-				if (yych == 'B') goto yy198;
-				if (yych >= 'E') goto yy192;
+				if (yych == 'B') goto yy199;
+				if (yych >= 'E') goto yy193;
 			}
 		} else {
 			if (yych <= 'b') {
-				if (yych == 'X') goto yy197;
-				if (yych >= 'b') goto yy198;
+				if (yych == 'X') goto yy198;
+				if (yych >= 'b') goto yy199;
 			} else {
 				if (yych <= 'e') {
-					if (yych >= 'e') goto yy192;
+					if (yych >= 'e') goto yy193;
 				} else {
-					if (yych == 'x') goto yy197;
+					if (yych == 'x') goto yy198;
 				}
 			}
 		}
-yy172:
-		YYDEBUG(172, *YYCURSOR);
+yy173:
+		YYDEBUG(173, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1512 "Zend/zend_language_scanner.l"
+#line 1516 "Zend/zend_language_scanner.l"
 		{
 	if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */
 		zendlval->value.lval = strtol(yytext, NULL, 0);
@@ -2964,35 +2972,35 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	zendlval->type = IS_LONG;
 	return T_LNUMBER;
 }
-#line 2968 "Zend/zend_language_scanner.c"
-yy173:
-		YYDEBUG(173, *YYCURSOR);
+#line 2976 "Zend/zend_language_scanner.c"
+yy174:
+		YYDEBUG(174, *YYCURSOR);
 		yyaccept = 2;
 		yych = *(YYMARKER = ++YYCURSOR);
 		if (yych <= '9') {
-			if (yych == '.') goto yy187;
-			if (yych <= '/') goto yy172;
-			goto yy190;
+			if (yych == '.') goto yy188;
+			if (yych <= '/') goto yy173;
+			goto yy191;
 		} else {
 			if (yych <= 'E') {
-				if (yych <= 'D') goto yy172;
-				goto yy192;
+				if (yych <= 'D') goto yy173;
+				goto yy193;
 			} else {
-				if (yych == 'e') goto yy192;
-				goto yy172;
+				if (yych == 'e') goto yy193;
+				goto yy173;
 			}
 		}
-yy174:
-		YYDEBUG(174, *YYCURSOR);
-		yych = *++YYCURSOR;
-		goto yy186;
 yy175:
 		YYDEBUG(175, *YYCURSOR);
-		++YYCURSOR;
+		yych = *++YYCURSOR;
+		goto yy187;
 yy176:
 		YYDEBUG(176, *YYCURSOR);
+		++YYCURSOR;
+yy177:
+		YYDEBUG(177, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1909 "Zend/zend_language_scanner.l"
+#line 1913 "Zend/zend_language_scanner.l"
 		{
 	while (YYCURSOR < YYLIMIT) {
 		switch (*YYCURSOR++) {
@@ -3026,14 +3034,14 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 
 	return T_COMMENT;
 }
-#line 3030 "Zend/zend_language_scanner.c"
-yy177:
-		YYDEBUG(177, *YYCURSOR);
-		++YYCURSOR;
+#line 3038 "Zend/zend_language_scanner.c"
 yy178:
 		YYDEBUG(178, *YYCURSOR);
+		++YYCURSOR;
+yy179:
+		YYDEBUG(179, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2000 "Zend/zend_language_scanner.l"
+#line 2004 "Zend/zend_language_scanner.l"
 		{
 	register char *s, *t;
 	char *end;
@@ -3101,14 +3109,14 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	}
 	return T_CONSTANT_ENCAPSED_STRING;
 }
-#line 3105 "Zend/zend_language_scanner.c"
-yy179:
-		YYDEBUG(179, *YYCURSOR);
-		++YYCURSOR;
+#line 3113 "Zend/zend_language_scanner.c"
 yy180:
 		YYDEBUG(180, *YYCURSOR);
+		++YYCURSOR;
+yy181:
+		YYDEBUG(181, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2069 "Zend/zend_language_scanner.l"
+#line 2073 "Zend/zend_language_scanner.l"
 		{
 	int bprefix = (yytext[0] != '"') ? 1 : 0;
 
@@ -3149,24 +3157,24 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	BEGIN(ST_DOUBLE_QUOTES);
 	return '"';
 }
-#line 3153 "Zend/zend_language_scanner.c"
-yy181:
-		YYDEBUG(181, *YYCURSOR);
-		++YYCURSOR;
+#line 3161 "Zend/zend_language_scanner.c"
+yy182:
 		YYDEBUG(182, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(183, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2159 "Zend/zend_language_scanner.l"
+#line 2163 "Zend/zend_language_scanner.l"
 		{
 	BEGIN(ST_BACKQUOTE);
 	return '`';
 }
-#line 3164 "Zend/zend_language_scanner.c"
-yy183:
-		YYDEBUG(183, *YYCURSOR);
-		++YYCURSOR;
+#line 3172 "Zend/zend_language_scanner.c"
+yy184:
 		YYDEBUG(184, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(185, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2422 "Zend/zend_language_scanner.l"
+#line 2426 "Zend/zend_language_scanner.l"
 		{
 	if (YYCURSOR > YYLIMIT) {
 		return 0;
@@ -3175,132 +3183,132 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	zend_error(E_COMPILE_WARNING,"Unexpected character in input:  '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
 	goto restart;
 }
-#line 3179 "Zend/zend_language_scanner.c"
-yy185:
-		YYDEBUG(185, *YYCURSOR);
+#line 3187 "Zend/zend_language_scanner.c"
+yy186:
+		YYDEBUG(186, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-yy186:
-		YYDEBUG(186, *YYCURSOR);
+yy187:
+		YYDEBUG(187, *YYCURSOR);
 		if (yybm[0+yych] & 4) {
-			goto yy185;
+			goto yy186;
 		}
 		goto yy124;
-yy187:
-		YYDEBUG(187, *YYCURSOR);
+yy188:
+		YYDEBUG(188, *YYCURSOR);
 		yyaccept = 3;
 		YYMARKER = ++YYCURSOR;
 		YYFILL(3);
 		yych = *YYCURSOR;
-		YYDEBUG(188, *YYCURSOR);
+		YYDEBUG(189, *YYCURSOR);
 		if (yybm[0+yych] & 8) {
-			goto yy187;
+			goto yy188;
 		}
-		if (yych == 'E') goto yy192;
-		if (yych == 'e') goto yy192;
-yy189:
-		YYDEBUG(189, *YYCURSOR);
+		if (yych == 'E') goto yy193;
+		if (yych == 'e') goto yy193;
+yy190:
+		YYDEBUG(190, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1577 "Zend/zend_language_scanner.l"
+#line 1581 "Zend/zend_language_scanner.l"
 		{
 	zendlval->value.dval = zend_strtod(yytext, NULL);
 	zendlval->type = IS_DOUBLE;
 	return T_DNUMBER;
 }
-#line 3212 "Zend/zend_language_scanner.c"
-yy190:
-		YYDEBUG(190, *YYCURSOR);
+#line 3220 "Zend/zend_language_scanner.c"
+yy191:
+		YYDEBUG(191, *YYCURSOR);
 		yyaccept = 2;
 		YYMARKER = ++YYCURSOR;
 		YYFILL(3);
 		yych = *YYCURSOR;
-		YYDEBUG(191, *YYCURSOR);
+		YYDEBUG(192, *YYCURSOR);
 		if (yych <= '9') {
-			if (yych == '.') goto yy187;
-			if (yych <= '/') goto yy172;
-			goto yy190;
+			if (yych == '.') goto yy188;
+			if (yych <= '/') goto yy173;
+			goto yy191;
 		} else {
 			if (yych <= 'E') {
-				if (yych <= 'D') goto yy172;
+				if (yych <= 'D') goto yy173;
 			} else {
-				if (yych != 'e') goto yy172;
+				if (yych != 'e') goto yy173;
 			}
 		}
-yy192:
-		YYDEBUG(192, *YYCURSOR);
+yy193:
+		YYDEBUG(193, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= ',') {
-			if (yych == '+') goto yy194;
+			if (yych == '+') goto yy195;
 		} else {
-			if (yych <= '-') goto yy194;
-			if (yych <= '/') goto yy193;
-			if (yych <= '9') goto yy195;
+			if (yych <= '-') goto yy195;
+			if (yych <= '/') goto yy194;
+			if (yych <= '9') goto yy196;
 		}
-yy193:
-		YYDEBUG(193, *YYCURSOR);
+yy194:
+		YYDEBUG(194, *YYCURSOR);
 		YYCURSOR = YYMARKER;
 		if (yyaccept <= 2) {
 			if (yyaccept <= 1) {
 				if (yyaccept <= 0) {
 					goto yy124;
 				} else {
-					goto yy138;
+					goto yy139;
 				}
 			} else {
-				goto yy172;
+				goto yy173;
 			}
 		} else {
 			if (yyaccept <= 4) {
 				if (yyaccept <= 3) {
-					goto yy189;
+					goto yy190;
 				} else {
-					goto yy238;
+					goto yy239;
 				}
 			} else {
-				goto yy254;
+				goto yy255;
 			}
 		}
-yy194:
-		YYDEBUG(194, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych <= '/') goto yy193;
-		if (yych >= ':') goto yy193;
 yy195:
 		YYDEBUG(195, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych <= '/') goto yy194;
+		if (yych >= ':') goto yy194;
+yy196:
+		YYDEBUG(196, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(196, *YYCURSOR);
-		if (yych <= '/') goto yy189;
-		if (yych <= '9') goto yy195;
-		goto yy189;
-yy197:
 		YYDEBUG(197, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yybm[0+yych] & 32) {
-			goto yy202;
-		}
-		goto yy193;
+		if (yych <= '/') goto yy190;
+		if (yych <= '9') goto yy196;
+		goto yy190;
 yy198:
 		YYDEBUG(198, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yybm[0+yych] & 16) {
-			goto yy199;
+		if (yybm[0+yych] & 32) {
+			goto yy203;
 		}
-		goto yy193;
+		goto yy194;
 yy199:
 		YYDEBUG(199, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yybm[0+yych] & 16) {
+			goto yy200;
+		}
+		goto yy194;
+yy200:
+		YYDEBUG(200, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(200, *YYCURSOR);
+		YYDEBUG(201, *YYCURSOR);
 		if (yybm[0+yych] & 16) {
-			goto yy199;
+			goto yy200;
 		}
-		YYDEBUG(201, *YYCURSOR);
+		YYDEBUG(202, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1487 "Zend/zend_language_scanner.l"
+#line 1491 "Zend/zend_language_scanner.l"
 		{
 	char *bin = yytext + 2; /* Skip "0b" */
 	int len = yyleng - 2;
@@ -3325,19 +3333,19 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		return T_DNUMBER;
 	}
 }
-#line 3329 "Zend/zend_language_scanner.c"
-yy202:
-		YYDEBUG(202, *YYCURSOR);
+#line 3337 "Zend/zend_language_scanner.c"
+yy203:
+		YYDEBUG(203, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(203, *YYCURSOR);
+		YYDEBUG(204, *YYCURSOR);
 		if (yybm[0+yych] & 32) {
-			goto yy202;
+			goto yy203;
 		}
-		YYDEBUG(204, *YYCURSOR);
+		YYDEBUG(205, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1533 "Zend/zend_language_scanner.l"
+#line 1537 "Zend/zend_language_scanner.l"
 		{
 	char *hex = yytext + 2; /* Skip "0x" */
 	int len = yyleng - 2;
@@ -3362,16 +3370,16 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		return T_DNUMBER;
 	}
 }
-#line 3366 "Zend/zend_language_scanner.c"
-yy205:
-		YYDEBUG(205, *YYCURSOR);
-		++YYCURSOR;
-		if ((yych = *YYCURSOR) == '\n') goto yy207;
-		if (yych == '\r') goto yy208;
+#line 3374 "Zend/zend_language_scanner.c"
 yy206:
 		YYDEBUG(206, *YYCURSOR);
+		++YYCURSOR;
+		if ((yych = *YYCURSOR) == '\n') goto yy208;
+		if (yych == '\r') goto yy209;
+yy207:
+		YYDEBUG(207, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1977 "Zend/zend_language_scanner.l"
+#line 1981 "Zend/zend_language_scanner.l"
 		{
 	zendlval->value.str.val = yytext; /* no copying - intentional */
 	zendlval->value.str.len = yyleng;
@@ -3379,137 +3387,137 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	BEGIN(INITIAL);
 	return T_CLOSE_TAG;  /* implicit ';' at php-end tag */
 }
-#line 3383 "Zend/zend_language_scanner.c"
-yy207:
-		YYDEBUG(207, *YYCURSOR);
-		yych = *++YYCURSOR;
-		goto yy206;
+#line 3391 "Zend/zend_language_scanner.c"
 yy208:
 		YYDEBUG(208, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == '\n') goto yy207;
-		goto yy206;
+		goto yy207;
 yy209:
 		YYDEBUG(209, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == '\n') goto yy208;
+		goto yy207;
+yy210:
+		YYDEBUG(210, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(210, *YYCURSOR);
+		YYDEBUG(211, *YYCURSOR);
 		if (yych <= '^') {
 			if (yych <= '9') {
-				if (yych >= '0') goto yy209;
+				if (yych >= '0') goto yy210;
 			} else {
-				if (yych <= '@') goto yy211;
-				if (yych <= 'Z') goto yy209;
+				if (yych <= '@') goto yy212;
+				if (yych <= 'Z') goto yy210;
 			}
 		} else {
 			if (yych <= '`') {
-				if (yych <= '_') goto yy209;
+				if (yych <= '_') goto yy210;
 			} else {
-				if (yych <= 'z') goto yy209;
-				if (yych >= 0x7F) goto yy209;
+				if (yych <= 'z') goto yy210;
+				if (yych >= 0x7F) goto yy210;
 			}
 		}
-yy211:
-		YYDEBUG(211, *YYCURSOR);
+yy212:
+		YYDEBUG(212, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1879 "Zend/zend_language_scanner.l"
+#line 1883 "Zend/zend_language_scanner.l"
 		{
 	zend_copy_value(zendlval, (yytext+1), (yyleng-1));
 	zendlval->type = IS_STRING;
 	return T_VARIABLE;
 }
-#line 3423 "Zend/zend_language_scanner.c"
-yy212:
-		YYDEBUG(212, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy213;
-		if (yych != 'r') goto yy186;
+#line 3431 "Zend/zend_language_scanner.c"
 yy213:
 		YYDEBUG(213, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'R') goto yy214;
+		if (yych != 'r') goto yy187;
+yy214:
+		YYDEBUG(214, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(214, *YYCURSOR);
+		YYDEBUG(215, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1432 "Zend/zend_language_scanner.l"
+#line 1436 "Zend/zend_language_scanner.l"
 		{
 	return T_LOGICAL_XOR;
 }
-#line 3441 "Zend/zend_language_scanner.c"
-yy215:
-		YYDEBUG(215, *YYCURSOR);
+#line 3449 "Zend/zend_language_scanner.c"
+yy216:
+		YYDEBUG(216, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(216, *YYCURSOR);
+		YYDEBUG(217, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1424 "Zend/zend_language_scanner.l"
+#line 1428 "Zend/zend_language_scanner.l"
 		{
 	return T_LOGICAL_OR;
 }
-#line 3454 "Zend/zend_language_scanner.c"
-yy217:
-		YYDEBUG(217, *YYCURSOR);
-		++YYCURSOR;
+#line 3462 "Zend/zend_language_scanner.c"
+yy218:
 		YYDEBUG(218, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(219, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1412 "Zend/zend_language_scanner.l"
+#line 1416 "Zend/zend_language_scanner.l"
 		{
 	return T_XOR_EQUAL;
 }
-#line 3464 "Zend/zend_language_scanner.c"
-yy219:
-		YYDEBUG(219, *YYCURSOR);
-		++YYCURSOR;
+#line 3472 "Zend/zend_language_scanner.c"
+yy220:
 		YYDEBUG(220, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(221, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1416 "Zend/zend_language_scanner.l"
+#line 1420 "Zend/zend_language_scanner.l"
 		{
 	return T_BOOLEAN_OR;
 }
-#line 3474 "Zend/zend_language_scanner.c"
-yy221:
-		YYDEBUG(221, *YYCURSOR);
-		++YYCURSOR;
+#line 3482 "Zend/zend_language_scanner.c"
+yy222:
 		YYDEBUG(222, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(223, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1408 "Zend/zend_language_scanner.l"
+#line 1412 "Zend/zend_language_scanner.l"
 		{
 	return T_OR_EQUAL;
 }
-#line 3484 "Zend/zend_language_scanner.c"
-yy223:
-		YYDEBUG(223, *YYCURSOR);
-		++YYCURSOR;
+#line 3492 "Zend/zend_language_scanner.c"
+yy224:
 		YYDEBUG(224, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(225, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1420 "Zend/zend_language_scanner.l"
+#line 1424 "Zend/zend_language_scanner.l"
 		{
 	return T_BOOLEAN_AND;
 }
-#line 3494 "Zend/zend_language_scanner.c"
-yy225:
-		YYDEBUG(225, *YYCURSOR);
-		++YYCURSOR;
+#line 3502 "Zend/zend_language_scanner.c"
+yy226:
 		YYDEBUG(226, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(227, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1404 "Zend/zend_language_scanner.l"
+#line 1408 "Zend/zend_language_scanner.l"
 		{
 	return T_AND_EQUAL;
 }
-#line 3504 "Zend/zend_language_scanner.c"
-yy227:
-		YYDEBUG(227, *YYCURSOR);
-		++YYCURSOR;
-		if ((yych = *YYCURSOR) == '\n') goto yy231;
-		if (yych == '\r') goto yy232;
+#line 3512 "Zend/zend_language_scanner.c"
 yy228:
 		YYDEBUG(228, *YYCURSOR);
+		++YYCURSOR;
+		if ((yych = *YYCURSOR) == '\n') goto yy232;
+		if (yych == '\r') goto yy233;
+yy229:
+		YYDEBUG(229, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1986 "Zend/zend_language_scanner.l"
+#line 1990 "Zend/zend_language_scanner.l"
 		{
 	if (CG(asp_tags)) {
 		BEGIN(INITIAL);
@@ -3522,61 +3530,61 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 		return yytext[0];
 	}
 }
-#line 3526 "Zend/zend_language_scanner.c"
-yy229:
-		YYDEBUG(229, *YYCURSOR);
-		++YYCURSOR;
+#line 3534 "Zend/zend_language_scanner.c"
+yy230:
 		YYDEBUG(230, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(231, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1392 "Zend/zend_language_scanner.l"
+#line 1396 "Zend/zend_language_scanner.l"
 		{
 	return T_MOD_EQUAL;
 }
-#line 3536 "Zend/zend_language_scanner.c"
-yy231:
-		YYDEBUG(231, *YYCURSOR);
-		yych = *++YYCURSOR;
-		goto yy228;
+#line 3544 "Zend/zend_language_scanner.c"
 yy232:
 		YYDEBUG(232, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == '\n') goto yy231;
-		goto yy228;
+		goto yy229;
 yy233:
 		YYDEBUG(233, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == '\n') goto yy232;
+		goto yy229;
+yy234:
+		YYDEBUG(234, *YYCURSOR);
 		yyaccept = 3;
 		YYMARKER = ++YYCURSOR;
 		YYFILL(3);
 		yych = *YYCURSOR;
-		YYDEBUG(234, *YYCURSOR);
+		YYDEBUG(235, *YYCURSOR);
 		if (yych <= 'D') {
-			if (yych <= '/') goto yy189;
-			if (yych <= '9') goto yy233;
-			goto yy189;
+			if (yych <= '/') goto yy190;
+			if (yych <= '9') goto yy234;
+			goto yy190;
 		} else {
-			if (yych <= 'E') goto yy192;
-			if (yych == 'e') goto yy192;
-			goto yy189;
+			if (yych <= 'E') goto yy193;
+			if (yych == 'e') goto yy193;
+			goto yy190;
 		}
-yy235:
-		YYDEBUG(235, *YYCURSOR);
-		++YYCURSOR;
+yy236:
 		YYDEBUG(236, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(237, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1388 "Zend/zend_language_scanner.l"
+#line 1392 "Zend/zend_language_scanner.l"
 		{
 	return T_CONCAT_EQUAL;
 }
-#line 3571 "Zend/zend_language_scanner.c"
-yy237:
-		YYDEBUG(237, *YYCURSOR);
-		yyaccept = 4;
-		yych = *(YYMARKER = ++YYCURSOR);
-		if (yych == '*') goto yy242;
+#line 3579 "Zend/zend_language_scanner.c"
 yy238:
 		YYDEBUG(238, *YYCURSOR);
+		yyaccept = 4;
+		yych = *(YYMARKER = ++YYCURSOR);
+		if (yych == '*') goto yy243;
+yy239:
+		YYDEBUG(239, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1943 "Zend/zend_language_scanner.l"
+#line 1947 "Zend/zend_language_scanner.l"
 		{
 	int doc_com;
 
@@ -3610,281 +3618,281 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 
 	return T_COMMENT;
 }
-#line 3614 "Zend/zend_language_scanner.c"
-yy239:
-		YYDEBUG(239, *YYCURSOR);
-		yych = *++YYCURSOR;
-		goto yy176;
+#line 3622 "Zend/zend_language_scanner.c"
 yy240:
 		YYDEBUG(240, *YYCURSOR);
-		++YYCURSOR;
+		yych = *++YYCURSOR;
+		goto yy177;
+yy241:
 		YYDEBUG(241, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(242, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1384 "Zend/zend_language_scanner.l"
+#line 1388 "Zend/zend_language_scanner.l"
 		{
 	return T_DIV_EQUAL;
 }
-#line 3628 "Zend/zend_language_scanner.c"
-yy242:
-		YYDEBUG(242, *YYCURSOR);
+#line 3636 "Zend/zend_language_scanner.c"
+yy243:
+		YYDEBUG(243, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yybm[0+yych] & 64) {
-			goto yy243;
+			goto yy244;
 		}
-		goto yy193;
-yy243:
-		YYDEBUG(243, *YYCURSOR);
+		goto yy194;
+yy244:
+		YYDEBUG(244, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(244, *YYCURSOR);
+		YYDEBUG(245, *YYCURSOR);
 		if (yybm[0+yych] & 64) {
-			goto yy243;
+			goto yy244;
 		}
-		goto yy238;
-yy245:
-		YYDEBUG(245, *YYCURSOR);
-		++YYCURSOR;
+		goto yy239;
+yy246:
 		YYDEBUG(246, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(247, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1380 "Zend/zend_language_scanner.l"
+#line 1384 "Zend/zend_language_scanner.l"
 		{
 	return T_MUL_EQUAL;
 }
-#line 3655 "Zend/zend_language_scanner.c"
-yy247:
-		YYDEBUG(247, *YYCURSOR);
-		++YYCURSOR;
-		if ((yych = *YYCURSOR) == '=') goto yy251;
+#line 3663 "Zend/zend_language_scanner.c"
+yy248:
 		YYDEBUG(248, *YYCURSOR);
+		++YYCURSOR;
+		if ((yych = *YYCURSOR) == '=') goto yy252;
+		YYDEBUG(249, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1440 "Zend/zend_language_scanner.l"
+#line 1444 "Zend/zend_language_scanner.l"
 		{
 	return T_SR;
 }
-#line 3666 "Zend/zend_language_scanner.c"
-yy249:
-		YYDEBUG(249, *YYCURSOR);
-		++YYCURSOR;
+#line 3674 "Zend/zend_language_scanner.c"
+yy250:
 		YYDEBUG(250, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(251, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1368 "Zend/zend_language_scanner.l"
+#line 1372 "Zend/zend_language_scanner.l"
 		{
 	return T_IS_GREATER_OR_EQUAL;
 }
-#line 3676 "Zend/zend_language_scanner.c"
-yy251:
-		YYDEBUG(251, *YYCURSOR);
-		++YYCURSOR;
+#line 3684 "Zend/zend_language_scanner.c"
+yy252:
 		YYDEBUG(252, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(253, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1400 "Zend/zend_language_scanner.l"
+#line 1404 "Zend/zend_language_scanner.l"
 		{
 	return T_SR_EQUAL;
 }
-#line 3686 "Zend/zend_language_scanner.c"
-yy253:
-		YYDEBUG(253, *YYCURSOR);
-		yyaccept = 5;
-		yych = *(YYMARKER = ++YYCURSOR);
-		if (yych <= ';') goto yy254;
-		if (yych <= '<') goto yy269;
-		if (yych <= '=') goto yy267;
+#line 3694 "Zend/zend_language_scanner.c"
 yy254:
 		YYDEBUG(254, *YYCURSOR);
+		yyaccept = 5;
+		yych = *(YYMARKER = ++YYCURSOR);
+		if (yych <= ';') goto yy255;
+		if (yych <= '<') goto yy270;
+		if (yych <= '=') goto yy268;
+yy255:
+		YYDEBUG(255, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1436 "Zend/zend_language_scanner.l"
+#line 1440 "Zend/zend_language_scanner.l"
 		{
 	return T_SL;
 }
-#line 3701 "Zend/zend_language_scanner.c"
-yy255:
-		YYDEBUG(255, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy260;
-		if (yych == 's') goto yy260;
-		goto yy193;
+#line 3709 "Zend/zend_language_scanner.c"
 yy256:
 		YYDEBUG(256, *YYCURSOR);
-		++YYCURSOR;
+		yych = *++YYCURSOR;
+		if (yych == 'S') goto yy261;
+		if (yych == 's') goto yy261;
+		goto yy194;
+yy257:
 		YYDEBUG(257, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(258, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1364 "Zend/zend_language_scanner.l"
+#line 1368 "Zend/zend_language_scanner.l"
 		{
 	return T_IS_SMALLER_OR_EQUAL;
 }
-#line 3717 "Zend/zend_language_scanner.c"
-yy258:
-		YYDEBUG(258, *YYCURSOR);
-		++YYCURSOR;
+#line 3725 "Zend/zend_language_scanner.c"
 yy259:
 		YYDEBUG(259, *YYCURSOR);
+		++YYCURSOR;
+yy260:
+		YYDEBUG(260, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1360 "Zend/zend_language_scanner.l"
+#line 1364 "Zend/zend_language_scanner.l"
 		{
 	return T_IS_NOT_EQUAL;
 }
-#line 3728 "Zend/zend_language_scanner.c"
-yy260:
-		YYDEBUG(260, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy261;
-		if (yych != 'c') goto yy193;
+#line 3736 "Zend/zend_language_scanner.c"
 yy261:
 		YYDEBUG(261, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy262;
-		if (yych != 'r') goto yy193;
+		if (yych == 'C') goto yy262;
+		if (yych != 'c') goto yy194;
 yy262:
 		YYDEBUG(262, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy263;
-		if (yych != 'i') goto yy193;
+		if (yych == 'R') goto yy263;
+		if (yych != 'r') goto yy194;
 yy263:
 		YYDEBUG(263, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'P') goto yy264;
-		if (yych != 'p') goto yy193;
+		if (yych == 'I') goto yy264;
+		if (yych != 'i') goto yy194;
 yy264:
 		YYDEBUG(264, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy265;
-		if (yych != 't') goto yy193;
+		if (yych == 'P') goto yy265;
+		if (yych != 'p') goto yy194;
 yy265:
 		YYDEBUG(265, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy266;
+		if (yych != 't') goto yy194;
+yy266:
+		YYDEBUG(266, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(3);
 		yych = *YYCURSOR;
-		YYDEBUG(266, *YYCURSOR);
+		YYDEBUG(267, *YYCURSOR);
 		if (yych <= '\r') {
-			if (yych <= 0x08) goto yy193;
-			if (yych <= '\n') goto yy265;
-			if (yych <= '\f') goto yy193;
-			goto yy265;
+			if (yych <= 0x08) goto yy194;
+			if (yych <= '\n') goto yy266;
+			if (yych <= '\f') goto yy194;
+			goto yy266;
 		} else {
 			if (yych <= ' ') {
-				if (yych <= 0x1F) goto yy193;
-				goto yy265;
+				if (yych <= 0x1F) goto yy194;
+				goto yy266;
 			} else {
-				if (yych == '>') goto yy205;
-				goto yy193;
+				if (yych == '>') goto yy206;
+				goto yy194;
 			}
 		}
-yy267:
-		YYDEBUG(267, *YYCURSOR);
-		++YYCURSOR;
+yy268:
 		YYDEBUG(268, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(269, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1396 "Zend/zend_language_scanner.l"
+#line 1400 "Zend/zend_language_scanner.l"
 		{
 	return T_SL_EQUAL;
 }
-#line 3783 "Zend/zend_language_scanner.c"
-yy269:
-		YYDEBUG(269, *YYCURSOR);
+#line 3791 "Zend/zend_language_scanner.c"
+yy270:
+		YYDEBUG(270, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(2);
 		yych = *YYCURSOR;
-		YYDEBUG(270, *YYCURSOR);
+		YYDEBUG(271, *YYCURSOR);
 		if (yybm[0+yych] & 128) {
-			goto yy269;
+			goto yy270;
 		}
 		if (yych <= 'Z') {
 			if (yych <= '&') {
-				if (yych == '"') goto yy274;
-				goto yy193;
+				if (yych == '"') goto yy275;
+				goto yy194;
 			} else {
-				if (yych <= '\'') goto yy273;
-				if (yych <= '@') goto yy193;
+				if (yych <= '\'') goto yy274;
+				if (yych <= '@') goto yy194;
 			}
 		} else {
 			if (yych <= '`') {
-				if (yych != '_') goto yy193;
+				if (yych != '_') goto yy194;
 			} else {
-				if (yych <= 'z') goto yy271;
-				if (yych <= '~') goto yy193;
+				if (yych <= 'z') goto yy272;
+				if (yych <= '~') goto yy194;
 			}
 		}
-yy271:
-		YYDEBUG(271, *YYCURSOR);
+yy272:
+		YYDEBUG(272, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(2);
 		yych = *YYCURSOR;
-		YYDEBUG(272, *YYCURSOR);
+		YYDEBUG(273, *YYCURSOR);
 		if (yych <= '@') {
 			if (yych <= '\f') {
-				if (yych == '\n') goto yy278;
-				goto yy193;
+				if (yych == '\n') goto yy279;
+				goto yy194;
 			} else {
-				if (yych <= '\r') goto yy280;
-				if (yych <= '/') goto yy193;
-				if (yych <= '9') goto yy271;
-				goto yy193;
+				if (yych <= '\r') goto yy281;
+				if (yych <= '/') goto yy194;
+				if (yych <= '9') goto yy272;
+				goto yy194;
 			}
 		} else {
 			if (yych <= '_') {
-				if (yych <= 'Z') goto yy271;
-				if (yych <= '^') goto yy193;
-				goto yy271;
+				if (yych <= 'Z') goto yy272;
+				if (yych <= '^') goto yy194;
+				goto yy272;
 			} else {
-				if (yych <= '`') goto yy193;
-				if (yych <= 'z') goto yy271;
-				if (yych <= '~') goto yy193;
-				goto yy271;
+				if (yych <= '`') goto yy194;
+				if (yych <= 'z') goto yy272;
+				if (yych <= '~') goto yy194;
+				goto yy272;
 			}
 		}
-yy273:
-		YYDEBUG(273, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == '\'') goto yy193;
-		if (yych <= '/') goto yy282;
-		if (yych <= '9') goto yy193;
-		goto yy282;
 yy274:
 		YYDEBUG(274, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == '"') goto yy193;
-		if (yych <= '/') goto yy276;
-		if (yych <= '9') goto yy193;
-		goto yy276;
+		if (yych == '\'') goto yy194;
+		if (yych <= '/') goto yy283;
+		if (yych <= '9') goto yy194;
+		goto yy283;
 yy275:
 		YYDEBUG(275, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == '"') goto yy194;
+		if (yych <= '/') goto yy277;
+		if (yych <= '9') goto yy194;
+		goto yy277;
+yy276:
+		YYDEBUG(276, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(3);
 		yych = *YYCURSOR;
-yy276:
-		YYDEBUG(276, *YYCURSOR);
+yy277:
+		YYDEBUG(277, *YYCURSOR);
 		if (yych <= 'Z') {
 			if (yych <= '/') {
-				if (yych != '"') goto yy193;
+				if (yych != '"') goto yy194;
 			} else {
-				if (yych <= '9') goto yy275;
-				if (yych <= '@') goto yy193;
-				goto yy275;
+				if (yych <= '9') goto yy276;
+				if (yych <= '@') goto yy194;
+				goto yy276;
 			}
 		} else {
 			if (yych <= '`') {
-				if (yych == '_') goto yy275;
-				goto yy193;
+				if (yych == '_') goto yy276;
+				goto yy194;
 			} else {
-				if (yych <= 'z') goto yy275;
-				if (yych <= '~') goto yy193;
-				goto yy275;
+				if (yych <= 'z') goto yy276;
+				if (yych <= '~') goto yy194;
+				goto yy276;
 			}
 		}
-yy277:
-		YYDEBUG(277, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == '\n') goto yy278;
-		if (yych == '\r') goto yy280;
-		goto yy193;
 yy278:
 		YYDEBUG(278, *YYCURSOR);
-		++YYCURSOR;
+		yych = *++YYCURSOR;
+		if (yych == '\n') goto yy279;
+		if (yych == '\r') goto yy281;
+		goto yy194;
 yy279:
 		YYDEBUG(279, *YYCURSOR);
+		++YYCURSOR;
+yy280:
+		YYDEBUG(280, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2111 "Zend/zend_language_scanner.l"
+#line 2115 "Zend/zend_language_scanner.l"
 		{
 	char *s;
 	int bprefix = (yytext[0] != '<') ? 1 : 0;
@@ -3931,255 +3939,255 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 
 	return T_START_HEREDOC;
 }
-#line 3935 "Zend/zend_language_scanner.c"
-yy280:
-		YYDEBUG(280, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == '\n') goto yy278;
-		goto yy279;
+#line 3943 "Zend/zend_language_scanner.c"
 yy281:
 		YYDEBUG(281, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == '\n') goto yy279;
+		goto yy280;
+yy282:
+		YYDEBUG(282, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(3);
 		yych = *YYCURSOR;
-yy282:
-		YYDEBUG(282, *YYCURSOR);
+yy283:
+		YYDEBUG(283, *YYCURSOR);
 		if (yych <= 'Z') {
 			if (yych <= '/') {
-				if (yych == '\'') goto yy277;
-				goto yy193;
+				if (yych == '\'') goto yy278;
+				goto yy194;
 			} else {
-				if (yych <= '9') goto yy281;
-				if (yych <= '@') goto yy193;
-				goto yy281;
+				if (yych <= '9') goto yy282;
+				if (yych <= '@') goto yy194;
+				goto yy282;
 			}
 		} else {
 			if (yych <= '`') {
-				if (yych == '_') goto yy281;
-				goto yy193;
+				if (yych == '_') goto yy282;
+				goto yy194;
 			} else {
-				if (yych <= 'z') goto yy281;
-				if (yych <= '~') goto yy193;
-				goto yy281;
+				if (yych <= 'z') goto yy282;
+				if (yych <= '~') goto yy194;
+				goto yy282;
 			}
 		}
-yy283:
-		YYDEBUG(283, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych != '=') goto yy259;
+yy284:
 		YYDEBUG(284, *YYCURSOR);
-		++YYCURSOR;
+		yych = *++YYCURSOR;
+		if (yych != '=') goto yy260;
 		YYDEBUG(285, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(286, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1352 "Zend/zend_language_scanner.l"
+#line 1356 "Zend/zend_language_scanner.l"
 		{
 	return T_IS_NOT_IDENTICAL;
 }
-#line 3979 "Zend/zend_language_scanner.c"
-yy286:
-		YYDEBUG(286, *YYCURSOR);
-		++YYCURSOR;
+#line 3987 "Zend/zend_language_scanner.c"
+yy287:
 		YYDEBUG(287, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(288, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1372 "Zend/zend_language_scanner.l"
+#line 1376 "Zend/zend_language_scanner.l"
 		{
 	return T_PLUS_EQUAL;
 }
-#line 3989 "Zend/zend_language_scanner.c"
-yy288:
-		YYDEBUG(288, *YYCURSOR);
-		++YYCURSOR;
+#line 3997 "Zend/zend_language_scanner.c"
+yy289:
 		YYDEBUG(289, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(290, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1340 "Zend/zend_language_scanner.l"
+#line 1344 "Zend/zend_language_scanner.l"
 		{
 	return T_INC;
 }
-#line 3999 "Zend/zend_language_scanner.c"
-yy290:
-		YYDEBUG(290, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy291;
-		if (yych != 's') goto yy186;
+#line 4007 "Zend/zend_language_scanner.c"
 yy291:
 		YYDEBUG(291, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy292;
-		if (yych != 't') goto yy186;
+		if (yych == 'S') goto yy292;
+		if (yych != 's') goto yy187;
 yy292:
 		YYDEBUG(292, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy293;
+		if (yych != 't') goto yy187;
+yy293:
+		YYDEBUG(293, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(293, *YYCURSOR);
+		YYDEBUG(294, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1328 "Zend/zend_language_scanner.l"
+#line 1332 "Zend/zend_language_scanner.l"
 		{
 	return T_LIST;
 }
-#line 4022 "Zend/zend_language_scanner.c"
-yy294:
-		YYDEBUG(294, *YYCURSOR);
-		++YYCURSOR;
-		if ((yych = *YYCURSOR) == '=') goto yy298;
+#line 4030 "Zend/zend_language_scanner.c"
+yy295:
 		YYDEBUG(295, *YYCURSOR);
+		++YYCURSOR;
+		if ((yych = *YYCURSOR) == '=') goto yy299;
+		YYDEBUG(296, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1356 "Zend/zend_language_scanner.l"
+#line 1360 "Zend/zend_language_scanner.l"
 		{
 	return T_IS_EQUAL;
 }
-#line 4033 "Zend/zend_language_scanner.c"
-yy296:
-		YYDEBUG(296, *YYCURSOR);
-		++YYCURSOR;
+#line 4041 "Zend/zend_language_scanner.c"
+yy297:
 		YYDEBUG(297, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(298, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1324 "Zend/zend_language_scanner.l"
+#line 1328 "Zend/zend_language_scanner.l"
 		{
 	return T_DOUBLE_ARROW;
 }
-#line 4043 "Zend/zend_language_scanner.c"
-yy298:
-		YYDEBUG(298, *YYCURSOR);
-		++YYCURSOR;
+#line 4051 "Zend/zend_language_scanner.c"
+yy299:
 		YYDEBUG(299, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(300, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1348 "Zend/zend_language_scanner.l"
+#line 1352 "Zend/zend_language_scanner.l"
 		{
 	return T_IS_IDENTICAL;
 }
-#line 4053 "Zend/zend_language_scanner.c"
-yy300:
-		YYDEBUG(300, *YYCURSOR);
+#line 4061 "Zend/zend_language_scanner.c"
+yy301:
+		YYDEBUG(301, *YYCURSOR);
 		yych = *++YYCURSOR;
 		YYDEBUG(-1, yych);
 		switch (yych) {
 		case 'C':
-		case 'c':	goto yy302;
+		case 'c':	goto yy303;
 		case 'D':
-		case 'd':	goto yy307;
+		case 'd':	goto yy308;
 		case 'F':
-		case 'f':	goto yy304;
+		case 'f':	goto yy305;
 		case 'H':
-		case 'h':	goto yy301;
+		case 'h':	goto yy302;
 		case 'L':
-		case 'l':	goto yy306;
+		case 'l':	goto yy307;
 		case 'M':
-		case 'm':	goto yy305;
+		case 'm':	goto yy306;
 		case 'N':
-		case 'n':	goto yy308;
+		case 'n':	goto yy309;
 		case 'T':
-		case 't':	goto yy303;
-		default:	goto yy186;
+		case 't':	goto yy304;
+		default:	goto yy187;
 		}
-yy301:
-		YYDEBUG(301, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy369;
-		if (yych == 'a') goto yy369;
-		goto yy186;
 yy302:
 		YYDEBUG(302, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy362;
-		if (yych == 'l') goto yy362;
-		goto yy186;
+		if (yych == 'A') goto yy370;
+		if (yych == 'a') goto yy370;
+		goto yy187;
 yy303:
 		YYDEBUG(303, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy355;
-		if (yych == 'r') goto yy355;
-		goto yy186;
+		if (yych == 'L') goto yy363;
+		if (yych == 'l') goto yy363;
+		goto yy187;
 yy304:
 		YYDEBUG(304, *YYCURSOR);
 		yych = *++YYCURSOR;
+		if (yych == 'R') goto yy356;
+		if (yych == 'r') goto yy356;
+		goto yy187;
+yy305:
+		YYDEBUG(305, *YYCURSOR);
+		yych = *++YYCURSOR;
 		if (yych <= 'U') {
-			if (yych == 'I') goto yy339;
-			if (yych <= 'T') goto yy186;
-			goto yy340;
+			if (yych == 'I') goto yy340;
+			if (yych <= 'T') goto yy187;
+			goto yy341;
 		} else {
 			if (yych <= 'i') {
-				if (yych <= 'h') goto yy186;
-				goto yy339;
+				if (yych <= 'h') goto yy187;
+				goto yy340;
 			} else {
-				if (yych == 'u') goto yy340;
-				goto yy186;
+				if (yych == 'u') goto yy341;
+				goto yy187;
 			}
 		}
-yy305:
-		YYDEBUG(305, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy331;
-		if (yych == 'e') goto yy331;
-		goto yy186;
 yy306:
 		YYDEBUG(306, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy325;
-		if (yych == 'i') goto yy325;
-		goto yy186;
+		if (yych == 'E') goto yy332;
+		if (yych == 'e') goto yy332;
+		goto yy187;
 yy307:
 		YYDEBUG(307, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy320;
-		if (yych == 'i') goto yy320;
-		goto yy186;
+		if (yych == 'I') goto yy326;
+		if (yych == 'i') goto yy326;
+		goto yy187;
 yy308:
 		YYDEBUG(308, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy309;
-		if (yych != 'a') goto yy186;
+		if (yych == 'I') goto yy321;
+		if (yych == 'i') goto yy321;
+		goto yy187;
 yy309:
 		YYDEBUG(309, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'M') goto yy310;
-		if (yych != 'm') goto yy186;
+		if (yych == 'A') goto yy310;
+		if (yych != 'a') goto yy187;
 yy310:
 		YYDEBUG(310, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy311;
-		if (yych != 'e') goto yy186;
+		if (yych == 'M') goto yy311;
+		if (yych != 'm') goto yy187;
 yy311:
 		YYDEBUG(311, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy312;
-		if (yych != 's') goto yy186;
+		if (yych == 'E') goto yy312;
+		if (yych != 'e') goto yy187;
 yy312:
 		YYDEBUG(312, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'P') goto yy313;
-		if (yych != 'p') goto yy186;
+		if (yych == 'S') goto yy313;
+		if (yych != 's') goto yy187;
 yy313:
 		YYDEBUG(313, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy314;
-		if (yych != 'a') goto yy186;
+		if (yych == 'P') goto yy314;
+		if (yych != 'p') goto yy187;
 yy314:
 		YYDEBUG(314, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy315;
-		if (yych != 'c') goto yy186;
+		if (yych == 'A') goto yy315;
+		if (yych != 'a') goto yy187;
 yy315:
 		YYDEBUG(315, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy316;
-		if (yych != 'e') goto yy186;
+		if (yych == 'C') goto yy316;
+		if (yych != 'c') goto yy187;
 yy316:
 		YYDEBUG(316, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych == 'E') goto yy317;
+		if (yych != 'e') goto yy187;
+yy317:
 		YYDEBUG(317, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych != '_') goto yy187;
 		YYDEBUG(318, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych != '_') goto yy187;
+		YYDEBUG(319, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(319, *YYCURSOR);
+		YYDEBUG(320, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1712 "Zend/zend_language_scanner.l"
+#line 1716 "Zend/zend_language_scanner.l"
 		{
 	if (CG(current_namespace)) {
 		*zendlval = *CG(current_namespace);
@@ -4189,27 +4197,27 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	}
 	return T_NS_C;
 }
-#line 4193 "Zend/zend_language_scanner.c"
-yy320:
-		YYDEBUG(320, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy321;
-		if (yych != 'r') goto yy186;
+#line 4201 "Zend/zend_language_scanner.c"
 yy321:
 		YYDEBUG(321, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych == 'R') goto yy322;
+		if (yych != 'r') goto yy187;
+yy322:
 		YYDEBUG(322, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych != '_') goto yy187;
 		YYDEBUG(323, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych != '_') goto yy187;
+		YYDEBUG(324, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(324, *YYCURSOR);
+		YYDEBUG(325, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1685 "Zend/zend_language_scanner.l"
+#line 1689 "Zend/zend_language_scanner.l"
 		{
 	char *filename = zend_get_compiled_filename(TSRMLS_C);
 	const size_t filename_len = strlen(filename);
@@ -4236,73 +4244,73 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	zendlval->type = IS_STRING;
 	return T_DIR;
 }
-#line 4240 "Zend/zend_language_scanner.c"
-yy325:
-		YYDEBUG(325, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy326;
-		if (yych != 'n') goto yy186;
+#line 4248 "Zend/zend_language_scanner.c"
 yy326:
 		YYDEBUG(326, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy327;
-		if (yych != 'e') goto yy186;
+		if (yych == 'N') goto yy327;
+		if (yych != 'n') goto yy187;
 yy327:
 		YYDEBUG(327, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych == 'E') goto yy328;
+		if (yych != 'e') goto yy187;
+yy328:
 		YYDEBUG(328, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych != '_') goto yy187;
 		YYDEBUG(329, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych != '_') goto yy187;
+		YYDEBUG(330, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(330, *YYCURSOR);
+		YYDEBUG(331, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1667 "Zend/zend_language_scanner.l"
+#line 1671 "Zend/zend_language_scanner.l"
 		{
 	zendlval->value.lval = CG(zend_lineno);
 	zendlval->type = IS_LONG;
 	return T_LINE;
 }
-#line 4271 "Zend/zend_language_scanner.c"
-yy331:
-		YYDEBUG(331, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy332;
-		if (yych != 't') goto yy186;
+#line 4279 "Zend/zend_language_scanner.c"
 yy332:
 		YYDEBUG(332, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'H') goto yy333;
-		if (yych != 'h') goto yy186;
+		if (yych == 'T') goto yy333;
+		if (yych != 't') goto yy187;
 yy333:
 		YYDEBUG(333, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy334;
-		if (yych != 'o') goto yy186;
+		if (yych == 'H') goto yy334;
+		if (yych != 'h') goto yy187;
 yy334:
 		YYDEBUG(334, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'D') goto yy335;
-		if (yych != 'd') goto yy186;
+		if (yych == 'O') goto yy335;
+		if (yych != 'o') goto yy187;
 yy335:
 		YYDEBUG(335, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych == 'D') goto yy336;
+		if (yych != 'd') goto yy187;
+yy336:
 		YYDEBUG(336, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych != '_') goto yy187;
 		YYDEBUG(337, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych != '_') goto yy187;
+		YYDEBUG(338, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(338, *YYCURSOR);
+		YYDEBUG(339, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1646 "Zend/zend_language_scanner.l"
+#line 1650 "Zend/zend_language_scanner.l"
 		{
 	const char *class_name = CG(active_class_entry) ? CG(active_class_entry)->name : NULL;
 	const char *func_name = CG(active_op_array)? CG(active_op_array)->function_name : NULL;
@@ -4323,58 +4331,58 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	zendlval->type = IS_STRING;
 	return T_METHOD_C;
 }
-#line 4327 "Zend/zend_language_scanner.c"
-yy339:
-		YYDEBUG(339, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy350;
-		if (yych == 'l') goto yy350;
-		goto yy186;
+#line 4335 "Zend/zend_language_scanner.c"
 yy340:
 		YYDEBUG(340, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy341;
-		if (yych != 'n') goto yy186;
+		if (yych == 'L') goto yy351;
+		if (yych == 'l') goto yy351;
+		goto yy187;
 yy341:
 		YYDEBUG(341, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy342;
-		if (yych != 'c') goto yy186;
+		if (yych == 'N') goto yy342;
+		if (yych != 'n') goto yy187;
 yy342:
 		YYDEBUG(342, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy343;
-		if (yych != 't') goto yy186;
+		if (yych == 'C') goto yy343;
+		if (yych != 'c') goto yy187;
 yy343:
 		YYDEBUG(343, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy344;
-		if (yych != 'i') goto yy186;
+		if (yych == 'T') goto yy344;
+		if (yych != 't') goto yy187;
 yy344:
 		YYDEBUG(344, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy345;
-		if (yych != 'o') goto yy186;
+		if (yych == 'I') goto yy345;
+		if (yych != 'i') goto yy187;
 yy345:
 		YYDEBUG(345, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy346;
-		if (yych != 'n') goto yy186;
+		if (yych == 'O') goto yy346;
+		if (yych != 'o') goto yy187;
 yy346:
 		YYDEBUG(346, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych == 'N') goto yy347;
+		if (yych != 'n') goto yy187;
+yy347:
 		YYDEBUG(347, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych != '_') goto yy187;
 		YYDEBUG(348, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych != '_') goto yy187;
+		YYDEBUG(349, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(349, *YYCURSOR);
+		YYDEBUG(350, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1630 "Zend/zend_language_scanner.l"
+#line 1634 "Zend/zend_language_scanner.l"
 		{
 	const char *func_name = NULL;
 
@@ -4390,27 +4398,27 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	zendlval->type = IS_STRING;
 	return T_FUNC_C;
 }
-#line 4394 "Zend/zend_language_scanner.c"
-yy350:
-		YYDEBUG(350, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy351;
-		if (yych != 'e') goto yy186;
+#line 4402 "Zend/zend_language_scanner.c"
 yy351:
 		YYDEBUG(351, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych == 'E') goto yy352;
+		if (yych != 'e') goto yy187;
+yy352:
 		YYDEBUG(352, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych != '_') goto yy187;
 		YYDEBUG(353, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych != '_') goto yy187;
+		YYDEBUG(354, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(354, *YYCURSOR);
+		YYDEBUG(355, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1673 "Zend/zend_language_scanner.l"
+#line 1677 "Zend/zend_language_scanner.l"
 		{
 	char *filename = zend_get_compiled_filename(TSRMLS_C);
 
@@ -4422,37 +4430,37 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	zendlval->type = IS_STRING;
 	return T_FILE;
 }
-#line 4426 "Zend/zend_language_scanner.c"
-yy355:
-		YYDEBUG(355, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy356;
-		if (yych != 'a') goto yy186;
+#line 4434 "Zend/zend_language_scanner.c"
 yy356:
 		YYDEBUG(356, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy357;
-		if (yych != 'i') goto yy186;
+		if (yych == 'A') goto yy357;
+		if (yych != 'a') goto yy187;
 yy357:
 		YYDEBUG(357, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy358;
-		if (yych != 't') goto yy186;
+		if (yych == 'I') goto yy358;
+		if (yych != 'i') goto yy187;
 yy358:
 		YYDEBUG(358, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych == 'T') goto yy359;
+		if (yych != 't') goto yy187;
+yy359:
 		YYDEBUG(359, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych != '_') goto yy187;
 		YYDEBUG(360, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych != '_') goto yy187;
+		YYDEBUG(361, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(361, *YYCURSOR);
+		YYDEBUG(362, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1610 "Zend/zend_language_scanner.l"
+#line 1614 "Zend/zend_language_scanner.l"
 		{
 	const char *trait_name = NULL;
 	
@@ -4472,37 +4480,37 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	
 	return T_TRAIT_C;
 }
-#line 4476 "Zend/zend_language_scanner.c"
-yy362:
-		YYDEBUG(362, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy363;
-		if (yych != 'a') goto yy186;
+#line 4484 "Zend/zend_language_scanner.c"
 yy363:
 		YYDEBUG(363, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy364;
-		if (yych != 's') goto yy186;
+		if (yych == 'A') goto yy364;
+		if (yych != 'a') goto yy187;
 yy364:
 		YYDEBUG(364, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych == 'S') goto yy365;
-		if (yych != 's') goto yy186;
+		if (yych != 's') goto yy187;
 yy365:
 		YYDEBUG(365, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych == 'S') goto yy366;
+		if (yych != 's') goto yy187;
+yy366:
 		YYDEBUG(366, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych != '_') goto yy187;
 		YYDEBUG(367, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych != '_') goto yy187;
+		YYDEBUG(368, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(368, *YYCURSOR);
+		YYDEBUG(369, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1583 "Zend/zend_language_scanner.l"
+#line 1587 "Zend/zend_language_scanner.l"
 		{
 	const char *class_name = NULL;
 	
@@ -4529,2681 +4537,2709 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	}
 	return T_CLASS_C;
 }
-#line 4533 "Zend/zend_language_scanner.c"
-yy369:
-		YYDEBUG(369, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy370;
-		if (yych != 'l') goto yy186;
+#line 4541 "Zend/zend_language_scanner.c"
 yy370:
 		YYDEBUG(370, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy371;
-		if (yych != 't') goto yy186;
+		if (yych == 'L') goto yy371;
+		if (yych != 'l') goto yy187;
 yy371:
 		YYDEBUG(371, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych != '_') goto yy186;
+		if (yych == 'T') goto yy372;
+		if (yych != 't') goto yy187;
+yy372:
 		YYDEBUG(372, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy373;
-		if (yych != 'c') goto yy186;
-yy373:
+		if (yych != '_') goto yy187;
 		YYDEBUG(373, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy374;
-		if (yych != 'o') goto yy186;
+		if (yych == 'C') goto yy374;
+		if (yych != 'c') goto yy187;
 yy374:
 		YYDEBUG(374, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'M') goto yy375;
-		if (yych != 'm') goto yy186;
+		if (yych == 'O') goto yy375;
+		if (yych != 'o') goto yy187;
 yy375:
 		YYDEBUG(375, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'P') goto yy376;
-		if (yych != 'p') goto yy186;
+		if (yych == 'M') goto yy376;
+		if (yych != 'm') goto yy187;
 yy376:
 		YYDEBUG(376, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy377;
-		if (yych != 'i') goto yy186;
+		if (yych == 'P') goto yy377;
+		if (yych != 'p') goto yy187;
 yy377:
 		YYDEBUG(377, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy378;
-		if (yych != 'l') goto yy186;
+		if (yych == 'I') goto yy378;
+		if (yych != 'i') goto yy187;
 yy378:
 		YYDEBUG(378, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy379;
-		if (yych != 'e') goto yy186;
+		if (yych == 'L') goto yy379;
+		if (yych != 'l') goto yy187;
 yy379:
 		YYDEBUG(379, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy380;
-		if (yych != 'r') goto yy186;
+		if (yych == 'E') goto yy380;
+		if (yych != 'e') goto yy187;
 yy380:
 		YYDEBUG(380, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'R') goto yy381;
+		if (yych != 'r') goto yy187;
+yy381:
+		YYDEBUG(381, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(381, *YYCURSOR);
+		YYDEBUG(382, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1292 "Zend/zend_language_scanner.l"
+#line 1296 "Zend/zend_language_scanner.l"
 		{
 	return T_HALT_COMPILER;
 }
-#line 4599 "Zend/zend_language_scanner.c"
-yy382:
-		YYDEBUG(382, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy386;
-		if (yych == 's') goto yy386;
-		goto yy186;
+#line 4607 "Zend/zend_language_scanner.c"
 yy383:
 		YYDEBUG(383, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy384;
-		if (yych != 'e') goto yy186;
+		if (yych == 'S') goto yy387;
+		if (yych == 's') goto yy387;
+		goto yy187;
 yy384:
 		YYDEBUG(384, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'E') goto yy385;
+		if (yych != 'e') goto yy187;
+yy385:
+		YYDEBUG(385, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(385, *YYCURSOR);
+		YYDEBUG(386, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1272 "Zend/zend_language_scanner.l"
+#line 1276 "Zend/zend_language_scanner.l"
 		{
 	return T_USE;
 }
-#line 4623 "Zend/zend_language_scanner.c"
-yy386:
-		YYDEBUG(386, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy387;
-		if (yych != 'e') goto yy186;
+#line 4631 "Zend/zend_language_scanner.c"
 yy387:
 		YYDEBUG(387, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy388;
-		if (yych != 't') goto yy186;
+		if (yych == 'E') goto yy388;
+		if (yych != 'e') goto yy187;
 yy388:
 		YYDEBUG(388, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy389;
+		if (yych != 't') goto yy187;
+yy389:
+		YYDEBUG(389, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(389, *YYCURSOR);
+		YYDEBUG(390, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1320 "Zend/zend_language_scanner.l"
+#line 1324 "Zend/zend_language_scanner.l"
 		{
 	return T_UNSET;
 }
-#line 4646 "Zend/zend_language_scanner.c"
-yy390:
-		YYDEBUG(390, *YYCURSOR);
+#line 4654 "Zend/zend_language_scanner.c"
+yy391:
+		YYDEBUG(391, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(7);
 		yych = *YYCURSOR;
-yy391:
-		YYDEBUG(391, *YYCURSOR);
+yy392:
+		YYDEBUG(392, *YYCURSOR);
 		if (yych <= 'S') {
 			if (yych <= 'D') {
 				if (yych <= ' ') {
-					if (yych == '\t') goto yy390;
-					if (yych <= 0x1F) goto yy193;
-					goto yy390;
+					if (yych == '\t') goto yy391;
+					if (yych <= 0x1F) goto yy194;
+					goto yy391;
 				} else {
 					if (yych <= 'A') {
-						if (yych <= '@') goto yy193;
-						goto yy395;
+						if (yych <= '@') goto yy194;
+						goto yy396;
 					} else {
-						if (yych <= 'B') goto yy393;
-						if (yych <= 'C') goto yy193;
-						goto yy398;
+						if (yych <= 'B') goto yy394;
+						if (yych <= 'C') goto yy194;
+						goto yy399;
 					}
 				}
 			} else {
 				if (yych <= 'I') {
-					if (yych == 'F') goto yy399;
-					if (yych <= 'H') goto yy193;
-					goto yy400;
+					if (yych == 'F') goto yy400;
+					if (yych <= 'H') goto yy194;
+					goto yy401;
 				} else {
 					if (yych <= 'O') {
-						if (yych <= 'N') goto yy193;
-						goto yy394;
+						if (yych <= 'N') goto yy194;
+						goto yy395;
 					} else {
-						if (yych <= 'Q') goto yy193;
-						if (yych <= 'R') goto yy397;
-						goto yy396;
+						if (yych <= 'Q') goto yy194;
+						if (yych <= 'R') goto yy398;
+						goto yy397;
 					}
 				}
 			}
 		} else {
 			if (yych <= 'f') {
 				if (yych <= 'a') {
-					if (yych == 'U') goto yy392;
-					if (yych <= '`') goto yy193;
-					goto yy395;
+					if (yych == 'U') goto yy393;
+					if (yych <= '`') goto yy194;
+					goto yy396;
 				} else {
 					if (yych <= 'c') {
-						if (yych <= 'b') goto yy393;
-						goto yy193;
+						if (yych <= 'b') goto yy394;
+						goto yy194;
 					} else {
-						if (yych <= 'd') goto yy398;
-						if (yych <= 'e') goto yy193;
-						goto yy399;
+						if (yych <= 'd') goto yy399;
+						if (yych <= 'e') goto yy194;
+						goto yy400;
 					}
 				}
 			} else {
 				if (yych <= 'q') {
 					if (yych <= 'i') {
-						if (yych <= 'h') goto yy193;
-						goto yy400;
+						if (yych <= 'h') goto yy194;
+						goto yy401;
 					} else {
-						if (yych == 'o') goto yy394;
-						goto yy193;
+						if (yych == 'o') goto yy395;
+						goto yy194;
 					}
 				} else {
 					if (yych <= 's') {
-						if (yych <= 'r') goto yy397;
-						goto yy396;
+						if (yych <= 'r') goto yy398;
+						goto yy397;
 					} else {
-						if (yych != 'u') goto yy193;
+						if (yych != 'u') goto yy194;
 					}
 				}
 			}
 		}
-yy392:
-		YYDEBUG(392, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy459;
-		if (yych == 'n') goto yy459;
-		goto yy193;
 yy393:
 		YYDEBUG(393, *YYCURSOR);
 		yych = *++YYCURSOR;
+		if (yych == 'N') goto yy460;
+		if (yych == 'n') goto yy460;
+		goto yy194;
+yy394:
+		YYDEBUG(394, *YYCURSOR);
+		yych = *++YYCURSOR;
 		if (yych <= 'O') {
-			if (yych == 'I') goto yy446;
-			if (yych <= 'N') goto yy193;
-			goto yy447;
+			if (yych == 'I') goto yy447;
+			if (yych <= 'N') goto yy194;
+			goto yy448;
 		} else {
 			if (yych <= 'i') {
-				if (yych <= 'h') goto yy193;
-				goto yy446;
+				if (yych <= 'h') goto yy194;
+				goto yy447;
 			} else {
-				if (yych == 'o') goto yy447;
-				goto yy193;
+				if (yych == 'o') goto yy448;
+				goto yy194;
 			}
 		}
-yy394:
-		YYDEBUG(394, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'B') goto yy438;
-		if (yych == 'b') goto yy438;
-		goto yy193;
 yy395:
 		YYDEBUG(395, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy431;
-		if (yych == 'r') goto yy431;
-		goto yy193;
+		if (yych == 'B') goto yy439;
+		if (yych == 'b') goto yy439;
+		goto yy194;
 yy396:
 		YYDEBUG(396, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy423;
-		if (yych == 't') goto yy423;
-		goto yy193;
+		if (yych == 'R') goto yy432;
+		if (yych == 'r') goto yy432;
+		goto yy194;
 yy397:
 		YYDEBUG(397, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy421;
-		if (yych == 'e') goto yy421;
-		goto yy193;
+		if (yych == 'T') goto yy424;
+		if (yych == 't') goto yy424;
+		goto yy194;
 yy398:
 		YYDEBUG(398, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy417;
-		if (yych == 'o') goto yy417;
-		goto yy193;
+		if (yych == 'E') goto yy422;
+		if (yych == 'e') goto yy422;
+		goto yy194;
 yy399:
 		YYDEBUG(399, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy410;
-		if (yych == 'l') goto yy410;
-		goto yy193;
+		if (yych == 'O') goto yy418;
+		if (yych == 'o') goto yy418;
+		goto yy194;
 yy400:
 		YYDEBUG(400, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy401;
-		if (yych != 'n') goto yy193;
+		if (yych == 'L') goto yy411;
+		if (yych == 'l') goto yy411;
+		goto yy194;
 yy401:
 		YYDEBUG(401, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy402;
-		if (yych != 't') goto yy193;
+		if (yych == 'N') goto yy402;
+		if (yych != 'n') goto yy194;
 yy402:
 		YYDEBUG(402, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy403;
-		if (yych != 'e') goto yy405;
+		if (yych == 'T') goto yy403;
+		if (yych != 't') goto yy194;
 yy403:
 		YYDEBUG(403, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'G') goto yy408;
-		if (yych == 'g') goto yy408;
-		goto yy193;
+		if (yych == 'E') goto yy404;
+		if (yych != 'e') goto yy406;
 yy404:
 		YYDEBUG(404, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'G') goto yy409;
+		if (yych == 'g') goto yy409;
+		goto yy194;
+yy405:
+		YYDEBUG(405, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-yy405:
-		YYDEBUG(405, *YYCURSOR);
+yy406:
+		YYDEBUG(406, *YYCURSOR);
 		if (yych <= 0x1F) {
-			if (yych == '\t') goto yy404;
-			goto yy193;
+			if (yych == '\t') goto yy405;
+			goto yy194;
 		} else {
-			if (yych <= ' ') goto yy404;
-			if (yych != ')') goto yy193;
+			if (yych <= ' ') goto yy405;
+			if (yych != ')') goto yy194;
 		}
-		YYDEBUG(406, *YYCURSOR);
-		++YYCURSOR;
 		YYDEBUG(407, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(408, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1220 "Zend/zend_language_scanner.l"
+#line 1224 "Zend/zend_language_scanner.l"
 		{
 	return T_INT_CAST;
 }
-#line 4822 "Zend/zend_language_scanner.c"
-yy408:
-		YYDEBUG(408, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy409;
-		if (yych != 'e') goto yy193;
+#line 4830 "Zend/zend_language_scanner.c"
 yy409:
 		YYDEBUG(409, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy404;
-		if (yych == 'r') goto yy404;
-		goto yy193;
+		if (yych == 'E') goto yy410;
+		if (yych != 'e') goto yy194;
 yy410:
 		YYDEBUG(410, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy411;
-		if (yych != 'o') goto yy193;
+		if (yych == 'R') goto yy405;
+		if (yych == 'r') goto yy405;
+		goto yy194;
 yy411:
 		YYDEBUG(411, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy412;
-		if (yych != 'a') goto yy193;
+		if (yych == 'O') goto yy412;
+		if (yych != 'o') goto yy194;
 yy412:
 		YYDEBUG(412, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy413;
-		if (yych != 't') goto yy193;
+		if (yych == 'A') goto yy413;
+		if (yych != 'a') goto yy194;
 yy413:
 		YYDEBUG(413, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy414;
+		if (yych != 't') goto yy194;
+yy414:
+		YYDEBUG(414, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(414, *YYCURSOR);
+		YYDEBUG(415, *YYCURSOR);
 		if (yych <= 0x1F) {
-			if (yych == '\t') goto yy413;
-			goto yy193;
+			if (yych == '\t') goto yy414;
+			goto yy194;
 		} else {
-			if (yych <= ' ') goto yy413;
-			if (yych != ')') goto yy193;
+			if (yych <= ' ') goto yy414;
+			if (yych != ')') goto yy194;
 		}
-		YYDEBUG(415, *YYCURSOR);
-		++YYCURSOR;
 		YYDEBUG(416, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(417, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1224 "Zend/zend_language_scanner.l"
+#line 1228 "Zend/zend_language_scanner.l"
 		{
 	return T_DOUBLE_CAST;
 }
-#line 4870 "Zend/zend_language_scanner.c"
-yy417:
-		YYDEBUG(417, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'U') goto yy418;
-		if (yych != 'u') goto yy193;
+#line 4878 "Zend/zend_language_scanner.c"
 yy418:
 		YYDEBUG(418, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'B') goto yy419;
-		if (yych != 'b') goto yy193;
+		if (yych == 'U') goto yy419;
+		if (yych != 'u') goto yy194;
 yy419:
 		YYDEBUG(419, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy420;
-		if (yych != 'l') goto yy193;
+		if (yych == 'B') goto yy420;
+		if (yych != 'b') goto yy194;
 yy420:
 		YYDEBUG(420, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy413;
-		if (yych == 'e') goto yy413;
-		goto yy193;
+		if (yych == 'L') goto yy421;
+		if (yych != 'l') goto yy194;
 yy421:
 		YYDEBUG(421, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy422;
-		if (yych != 'a') goto yy193;
+		if (yych == 'E') goto yy414;
+		if (yych == 'e') goto yy414;
+		goto yy194;
 yy422:
 		YYDEBUG(422, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy413;
-		if (yych == 'l') goto yy413;
-		goto yy193;
+		if (yych == 'A') goto yy423;
+		if (yych != 'a') goto yy194;
 yy423:
 		YYDEBUG(423, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy424;
-		if (yych != 'r') goto yy193;
+		if (yych == 'L') goto yy414;
+		if (yych == 'l') goto yy414;
+		goto yy194;
 yy424:
 		YYDEBUG(424, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy425;
-		if (yych != 'i') goto yy193;
+		if (yych == 'R') goto yy425;
+		if (yych != 'r') goto yy194;
 yy425:
 		YYDEBUG(425, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy426;
-		if (yych != 'n') goto yy193;
+		if (yych == 'I') goto yy426;
+		if (yych != 'i') goto yy194;
 yy426:
 		YYDEBUG(426, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'G') goto yy427;
-		if (yych != 'g') goto yy193;
+		if (yych == 'N') goto yy427;
+		if (yych != 'n') goto yy194;
 yy427:
 		YYDEBUG(427, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'G') goto yy428;
+		if (yych != 'g') goto yy194;
+yy428:
+		YYDEBUG(428, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(428, *YYCURSOR);
+		YYDEBUG(429, *YYCURSOR);
 		if (yych <= 0x1F) {
-			if (yych == '\t') goto yy427;
-			goto yy193;
+			if (yych == '\t') goto yy428;
+			goto yy194;
 		} else {
-			if (yych <= ' ') goto yy427;
-			if (yych != ')') goto yy193;
+			if (yych <= ' ') goto yy428;
+			if (yych != ')') goto yy194;
 		}
-		YYDEBUG(429, *YYCURSOR);
-		++YYCURSOR;
 		YYDEBUG(430, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(431, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1228 "Zend/zend_language_scanner.l"
+#line 1232 "Zend/zend_language_scanner.l"
 		{
 	return T_STRING_CAST;
 }
-#line 4944 "Zend/zend_language_scanner.c"
-yy431:
-		YYDEBUG(431, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy432;
-		if (yych != 'r') goto yy193;
+#line 4952 "Zend/zend_language_scanner.c"
 yy432:
 		YYDEBUG(432, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy433;
-		if (yych != 'a') goto yy193;
+		if (yych == 'R') goto yy433;
+		if (yych != 'r') goto yy194;
 yy433:
 		YYDEBUG(433, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'Y') goto yy434;
-		if (yych != 'y') goto yy193;
+		if (yych == 'A') goto yy434;
+		if (yych != 'a') goto yy194;
 yy434:
 		YYDEBUG(434, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'Y') goto yy435;
+		if (yych != 'y') goto yy194;
+yy435:
+		YYDEBUG(435, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(435, *YYCURSOR);
+		YYDEBUG(436, *YYCURSOR);
 		if (yych <= 0x1F) {
-			if (yych == '\t') goto yy434;
-			goto yy193;
+			if (yych == '\t') goto yy435;
+			goto yy194;
 		} else {
-			if (yych <= ' ') goto yy434;
-			if (yych != ')') goto yy193;
+			if (yych <= ' ') goto yy435;
+			if (yych != ')') goto yy194;
 		}
-		YYDEBUG(436, *YYCURSOR);
-		++YYCURSOR;
 		YYDEBUG(437, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(438, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1232 "Zend/zend_language_scanner.l"
+#line 1236 "Zend/zend_language_scanner.l"
 		{
 	return T_ARRAY_CAST;
 }
-#line 4981 "Zend/zend_language_scanner.c"
-yy438:
-		YYDEBUG(438, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'J') goto yy439;
-		if (yych != 'j') goto yy193;
+#line 4989 "Zend/zend_language_scanner.c"
 yy439:
 		YYDEBUG(439, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy440;
-		if (yych != 'e') goto yy193;
+		if (yych == 'J') goto yy440;
+		if (yych != 'j') goto yy194;
 yy440:
 		YYDEBUG(440, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy441;
-		if (yych != 'c') goto yy193;
+		if (yych == 'E') goto yy441;
+		if (yych != 'e') goto yy194;
 yy441:
 		YYDEBUG(441, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy442;
-		if (yych != 't') goto yy193;
+		if (yych == 'C') goto yy442;
+		if (yych != 'c') goto yy194;
 yy442:
 		YYDEBUG(442, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy443;
+		if (yych != 't') goto yy194;
+yy443:
+		YYDEBUG(443, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(443, *YYCURSOR);
+		YYDEBUG(444, *YYCURSOR);
 		if (yych <= 0x1F) {
-			if (yych == '\t') goto yy442;
-			goto yy193;
+			if (yych == '\t') goto yy443;
+			goto yy194;
 		} else {
-			if (yych <= ' ') goto yy442;
-			if (yych != ')') goto yy193;
+			if (yych <= ' ') goto yy443;
+			if (yych != ')') goto yy194;
 		}
-		YYDEBUG(444, *YYCURSOR);
-		++YYCURSOR;
 		YYDEBUG(445, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(446, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1236 "Zend/zend_language_scanner.l"
+#line 1240 "Zend/zend_language_scanner.l"
 		{
 	return T_OBJECT_CAST;
 }
-#line 5023 "Zend/zend_language_scanner.c"
-yy446:
-		YYDEBUG(446, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy456;
-		if (yych == 'n') goto yy456;
-		goto yy193;
+#line 5031 "Zend/zend_language_scanner.c"
 yy447:
 		YYDEBUG(447, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy448;
-		if (yych != 'o') goto yy193;
+		if (yych == 'N') goto yy457;
+		if (yych == 'n') goto yy457;
+		goto yy194;
 yy448:
 		YYDEBUG(448, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy449;
-		if (yych != 'l') goto yy193;
+		if (yych == 'O') goto yy449;
+		if (yych != 'o') goto yy194;
 yy449:
 		YYDEBUG(449, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy454;
-		if (yych == 'e') goto yy454;
-		goto yy451;
+		if (yych == 'L') goto yy450;
+		if (yych != 'l') goto yy194;
 yy450:
 		YYDEBUG(450, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'E') goto yy455;
+		if (yych == 'e') goto yy455;
+		goto yy452;
+yy451:
+		YYDEBUG(451, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-yy451:
-		YYDEBUG(451, *YYCURSOR);
+yy452:
+		YYDEBUG(452, *YYCURSOR);
 		if (yych <= 0x1F) {
-			if (yych == '\t') goto yy450;
-			goto yy193;
+			if (yych == '\t') goto yy451;
+			goto yy194;
 		} else {
-			if (yych <= ' ') goto yy450;
-			if (yych != ')') goto yy193;
+			if (yych <= ' ') goto yy451;
+			if (yych != ')') goto yy194;
 		}
-		YYDEBUG(452, *YYCURSOR);
-		++YYCURSOR;
 		YYDEBUG(453, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(454, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1240 "Zend/zend_language_scanner.l"
+#line 1244 "Zend/zend_language_scanner.l"
 		{
 	return T_BOOL_CAST;
 }
-#line 5068 "Zend/zend_language_scanner.c"
-yy454:
-		YYDEBUG(454, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy455;
-		if (yych != 'a') goto yy193;
+#line 5076 "Zend/zend_language_scanner.c"
 yy455:
 		YYDEBUG(455, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy450;
-		if (yych == 'n') goto yy450;
-		goto yy193;
+		if (yych == 'A') goto yy456;
+		if (yych != 'a') goto yy194;
 yy456:
 		YYDEBUG(456, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy457;
-		if (yych != 'a') goto yy193;
+		if (yych == 'N') goto yy451;
+		if (yych == 'n') goto yy451;
+		goto yy194;
 yy457:
 		YYDEBUG(457, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy458;
-		if (yych != 'r') goto yy193;
+		if (yych == 'A') goto yy458;
+		if (yych != 'a') goto yy194;
 yy458:
 		YYDEBUG(458, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'Y') goto yy427;
-		if (yych == 'y') goto yy427;
-		goto yy193;
+		if (yych == 'R') goto yy459;
+		if (yych != 'r') goto yy194;
 yy459:
 		YYDEBUG(459, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy460;
-		if (yych != 's') goto yy193;
+		if (yych == 'Y') goto yy428;
+		if (yych == 'y') goto yy428;
+		goto yy194;
 yy460:
 		YYDEBUG(460, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy461;
-		if (yych != 'e') goto yy193;
+		if (yych == 'S') goto yy461;
+		if (yych != 's') goto yy194;
 yy461:
 		YYDEBUG(461, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy462;
-		if (yych != 't') goto yy193;
+		if (yych == 'E') goto yy462;
+		if (yych != 'e') goto yy194;
 yy462:
 		YYDEBUG(462, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy463;
+		if (yych != 't') goto yy194;
+yy463:
+		YYDEBUG(463, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(463, *YYCURSOR);
+		YYDEBUG(464, *YYCURSOR);
 		if (yych <= 0x1F) {
-			if (yych == '\t') goto yy462;
-			goto yy193;
+			if (yych == '\t') goto yy463;
+			goto yy194;
 		} else {
-			if (yych <= ' ') goto yy462;
-			if (yych != ')') goto yy193;
+			if (yych <= ' ') goto yy463;
+			if (yych != ')') goto yy194;
 		}
-		YYDEBUG(464, *YYCURSOR);
-		++YYCURSOR;
 		YYDEBUG(465, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(466, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1244 "Zend/zend_language_scanner.l"
+#line 1248 "Zend/zend_language_scanner.l"
 		{
 	return T_UNSET_CAST;
 }
-#line 5132 "Zend/zend_language_scanner.c"
-yy466:
-		YYDEBUG(466, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy467;
-		if (yych != 'r') goto yy186;
+#line 5140 "Zend/zend_language_scanner.c"
 yy467:
 		YYDEBUG(467, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'R') goto yy468;
+		if (yych != 'r') goto yy187;
+yy468:
+		YYDEBUG(468, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(468, *YYCURSOR);
+		YYDEBUG(469, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1216 "Zend/zend_language_scanner.l"
+#line 1220 "Zend/zend_language_scanner.l"
 		{
 	return T_VAR;
 }
-#line 5150 "Zend/zend_language_scanner.c"
-yy469:
-		YYDEBUG(469, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'M') goto yy473;
-		if (yych == 'm') goto yy473;
-		goto yy186;
+#line 5158 "Zend/zend_language_scanner.c"
 yy470:
 		YYDEBUG(470, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'W') goto yy471;
-		if (yych != 'w') goto yy186;
+		if (yych == 'M') goto yy474;
+		if (yych == 'm') goto yy474;
+		goto yy187;
 yy471:
 		YYDEBUG(471, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'W') goto yy472;
+		if (yych != 'w') goto yy187;
+yy472:
+		YYDEBUG(472, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(472, *YYCURSOR);
+		YYDEBUG(473, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1208 "Zend/zend_language_scanner.l"
+#line 1212 "Zend/zend_language_scanner.l"
 		{
 	return T_NEW;
 }
-#line 5174 "Zend/zend_language_scanner.c"
-yy473:
-		YYDEBUG(473, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy474;
-		if (yych != 'e') goto yy186;
+#line 5182 "Zend/zend_language_scanner.c"
 yy474:
 		YYDEBUG(474, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy475;
-		if (yych != 's') goto yy186;
+		if (yych == 'E') goto yy475;
+		if (yych != 'e') goto yy187;
 yy475:
 		YYDEBUG(475, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'P') goto yy476;
-		if (yych != 'p') goto yy186;
+		if (yych == 'S') goto yy476;
+		if (yych != 's') goto yy187;
 yy476:
 		YYDEBUG(476, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy477;
-		if (yych != 'a') goto yy186;
+		if (yych == 'P') goto yy477;
+		if (yych != 'p') goto yy187;
 yy477:
 		YYDEBUG(477, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy478;
-		if (yych != 'c') goto yy186;
+		if (yych == 'A') goto yy478;
+		if (yych != 'a') goto yy187;
 yy478:
 		YYDEBUG(478, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy479;
-		if (yych != 'e') goto yy186;
+		if (yych == 'C') goto yy479;
+		if (yych != 'c') goto yy187;
 yy479:
 		YYDEBUG(479, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'E') goto yy480;
+		if (yych != 'e') goto yy187;
+yy480:
+		YYDEBUG(480, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(480, *YYCURSOR);
+		YYDEBUG(481, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1268 "Zend/zend_language_scanner.l"
+#line 1272 "Zend/zend_language_scanner.l"
 		{
 	return T_NAMESPACE;
 }
-#line 5217 "Zend/zend_language_scanner.c"
-yy481:
-		YYDEBUG(481, *YYCURSOR);
-		++YYCURSOR;
+#line 5225 "Zend/zend_language_scanner.c"
+yy482:
 		YYDEBUG(482, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(483, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1200 "Zend/zend_language_scanner.l"
+#line 1204 "Zend/zend_language_scanner.l"
 		{
 	return T_PAAMAYIM_NEKUDOTAYIM;
 }
-#line 5227 "Zend/zend_language_scanner.c"
-yy483:
-		YYDEBUG(483, *YYCURSOR);
+#line 5235 "Zend/zend_language_scanner.c"
+yy484:
+		YYDEBUG(484, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-yy484:
-		YYDEBUG(484, *YYCURSOR);
+yy485:
+		YYDEBUG(485, *YYCURSOR);
 		if (yych <= '\f') {
-			if (yych <= 0x08) goto yy140;
-			if (yych <= '\n') goto yy483;
-			goto yy140;
+			if (yych <= 0x08) goto yy141;
+			if (yych <= '\n') goto yy484;
+			goto yy141;
 		} else {
-			if (yych <= '\r') goto yy483;
-			if (yych == ' ') goto yy483;
-			goto yy140;
+			if (yych <= '\r') goto yy484;
+			if (yych == ' ') goto yy484;
+			goto yy141;
 		}
-yy485:
-		YYDEBUG(485, *YYCURSOR);
-		++YYCURSOR;
+yy486:
 		YYDEBUG(486, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(487, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1376 "Zend/zend_language_scanner.l"
+#line 1380 "Zend/zend_language_scanner.l"
 		{
 	return T_MINUS_EQUAL;
 }
-#line 5253 "Zend/zend_language_scanner.c"
-yy487:
-		YYDEBUG(487, *YYCURSOR);
-		++YYCURSOR;
+#line 5261 "Zend/zend_language_scanner.c"
+yy488:
 		YYDEBUG(488, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(489, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1344 "Zend/zend_language_scanner.l"
+#line 1348 "Zend/zend_language_scanner.l"
 		{
 	return T_DEC;
 }
-#line 5263 "Zend/zend_language_scanner.c"
-yy489:
-		YYDEBUG(489, *YYCURSOR);
-		++YYCURSOR;
+#line 5271 "Zend/zend_language_scanner.c"
+yy490:
 		YYDEBUG(490, *YYCURSOR);
+		++YYCURSOR;
+		YYDEBUG(491, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1170 "Zend/zend_language_scanner.l"
+#line 1174 "Zend/zend_language_scanner.l"
 		{
 	yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
 	return T_OBJECT_OPERATOR;
 }
-#line 5274 "Zend/zend_language_scanner.c"
-yy491:
-		YYDEBUG(491, *YYCURSOR);
+#line 5282 "Zend/zend_language_scanner.c"
+yy492:
+		YYDEBUG(492, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'O') {
-			if (yych == 'I') goto yy498;
-			if (yych <= 'N') goto yy186;
-			goto yy499;
+			if (yych == 'I') goto yy499;
+			if (yych <= 'N') goto yy187;
+			goto yy500;
 		} else {
 			if (yych <= 'i') {
-				if (yych <= 'h') goto yy186;
-				goto yy498;
+				if (yych <= 'h') goto yy187;
+				goto yy499;
 			} else {
-				if (yych == 'o') goto yy499;
-				goto yy186;
+				if (yych == 'o') goto yy500;
+				goto yy187;
 			}
 		}
-yy492:
-		YYDEBUG(492, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'B') goto yy493;
-		if (yych != 'b') goto yy186;
 yy493:
 		YYDEBUG(493, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy494;
-		if (yych != 'l') goto yy186;
+		if (yych == 'B') goto yy494;
+		if (yych != 'b') goto yy187;
 yy494:
 		YYDEBUG(494, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy495;
-		if (yych != 'i') goto yy186;
+		if (yych == 'L') goto yy495;
+		if (yych != 'l') goto yy187;
 yy495:
 		YYDEBUG(495, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy496;
-		if (yych != 'c') goto yy186;
+		if (yych == 'I') goto yy496;
+		if (yych != 'i') goto yy187;
 yy496:
 		YYDEBUG(496, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'C') goto yy497;
+		if (yych != 'c') goto yy187;
+yy497:
+		YYDEBUG(497, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(497, *YYCURSOR);
+		YYDEBUG(498, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1316 "Zend/zend_language_scanner.l"
+#line 1320 "Zend/zend_language_scanner.l"
 		{
 	return T_PUBLIC;
 }
-#line 5323 "Zend/zend_language_scanner.c"
-yy498:
-		YYDEBUG(498, *YYCURSOR);
+#line 5331 "Zend/zend_language_scanner.c"
+yy499:
+		YYDEBUG(499, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'V') {
-			if (yych == 'N') goto yy507;
-			if (yych <= 'U') goto yy186;
-			goto yy508;
+			if (yych == 'N') goto yy508;
+			if (yych <= 'U') goto yy187;
+			goto yy509;
 		} else {
 			if (yych <= 'n') {
-				if (yych <= 'm') goto yy186;
-				goto yy507;
+				if (yych <= 'm') goto yy187;
+				goto yy508;
 			} else {
-				if (yych == 'v') goto yy508;
-				goto yy186;
+				if (yych == 'v') goto yy509;
+				goto yy187;
 			}
 		}
-yy499:
-		YYDEBUG(499, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy500;
-		if (yych != 't') goto yy186;
 yy500:
 		YYDEBUG(500, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy501;
-		if (yych != 'e') goto yy186;
+		if (yych == 'T') goto yy501;
+		if (yych != 't') goto yy187;
 yy501:
 		YYDEBUG(501, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy502;
-		if (yych != 'c') goto yy186;
+		if (yych == 'E') goto yy502;
+		if (yych != 'e') goto yy187;
 yy502:
 		YYDEBUG(502, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy503;
-		if (yych != 't') goto yy186;
+		if (yych == 'C') goto yy503;
+		if (yych != 'c') goto yy187;
 yy503:
 		YYDEBUG(503, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy504;
-		if (yych != 'e') goto yy186;
+		if (yych == 'T') goto yy504;
+		if (yych != 't') goto yy187;
 yy504:
 		YYDEBUG(504, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'D') goto yy505;
-		if (yych != 'd') goto yy186;
+		if (yych == 'E') goto yy505;
+		if (yych != 'e') goto yy187;
 yy505:
 		YYDEBUG(505, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'D') goto yy506;
+		if (yych != 'd') goto yy187;
+yy506:
+		YYDEBUG(506, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(506, *YYCURSOR);
+		YYDEBUG(507, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1312 "Zend/zend_language_scanner.l"
+#line 1316 "Zend/zend_language_scanner.l"
 		{
 	return T_PROTECTED;
 }
-#line 5382 "Zend/zend_language_scanner.c"
-yy507:
-		YYDEBUG(507, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy513;
-		if (yych == 't') goto yy513;
-		goto yy186;
+#line 5390 "Zend/zend_language_scanner.c"
 yy508:
 		YYDEBUG(508, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy509;
-		if (yych != 'a') goto yy186;
+		if (yych == 'T') goto yy514;
+		if (yych == 't') goto yy514;
+		goto yy187;
 yy509:
 		YYDEBUG(509, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy510;
-		if (yych != 't') goto yy186;
+		if (yych == 'A') goto yy510;
+		if (yych != 'a') goto yy187;
 yy510:
 		YYDEBUG(510, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy511;
-		if (yych != 'e') goto yy186;
+		if (yych == 'T') goto yy511;
+		if (yych != 't') goto yy187;
 yy511:
 		YYDEBUG(511, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'E') goto yy512;
+		if (yych != 'e') goto yy187;
+yy512:
+		YYDEBUG(512, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(512, *YYCURSOR);
+		YYDEBUG(513, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1308 "Zend/zend_language_scanner.l"
+#line 1312 "Zend/zend_language_scanner.l"
 		{
 	return T_PRIVATE;
 }
-#line 5416 "Zend/zend_language_scanner.c"
-yy513:
-		YYDEBUG(513, *YYCURSOR);
+#line 5424 "Zend/zend_language_scanner.c"
+yy514:
+		YYDEBUG(514, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(514, *YYCURSOR);
+		YYDEBUG(515, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1146 "Zend/zend_language_scanner.l"
+#line 1150 "Zend/zend_language_scanner.l"
 		{
 	return T_PRINT;
 }
-#line 5429 "Zend/zend_language_scanner.c"
-yy515:
-		YYDEBUG(515, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy520;
-		if (yych == 'o') goto yy520;
-		goto yy186;
+#line 5437 "Zend/zend_language_scanner.c"
 yy516:
 		YYDEBUG(516, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy517;
-		if (yych != 't') goto yy186;
+		if (yych == 'O') goto yy521;
+		if (yych == 'o') goto yy521;
+		goto yy187;
 yy517:
 		YYDEBUG(517, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy518;
-		if (yych != 'o') goto yy186;
+		if (yych == 'T') goto yy518;
+		if (yych != 't') goto yy187;
 yy518:
 		YYDEBUG(518, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'O') goto yy519;
+		if (yych != 'o') goto yy187;
+yy519:
+		YYDEBUG(519, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(519, *YYCURSOR);
+		YYDEBUG(520, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1138 "Zend/zend_language_scanner.l"
+#line 1142 "Zend/zend_language_scanner.l"
 		{
 	return T_GOTO;
 }
-#line 5458 "Zend/zend_language_scanner.c"
-yy520:
-		YYDEBUG(520, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'B') goto yy521;
-		if (yych != 'b') goto yy186;
+#line 5466 "Zend/zend_language_scanner.c"
 yy521:
 		YYDEBUG(521, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy522;
-		if (yych != 'a') goto yy186;
+		if (yych == 'B') goto yy522;
+		if (yych != 'b') goto yy187;
 yy522:
 		YYDEBUG(522, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy523;
-		if (yych != 'l') goto yy186;
+		if (yych == 'A') goto yy523;
+		if (yych != 'a') goto yy187;
 yy523:
 		YYDEBUG(523, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'L') goto yy524;
+		if (yych != 'l') goto yy187;
+yy524:
+		YYDEBUG(524, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(524, *YYCURSOR);
+		YYDEBUG(525, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1280 "Zend/zend_language_scanner.l"
+#line 1284 "Zend/zend_language_scanner.l"
 		{
 	return T_GLOBAL;
 }
-#line 5486 "Zend/zend_language_scanner.c"
-yy525:
-		YYDEBUG(525, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == '<') goto yy533;
-		goto yy193;
+#line 5494 "Zend/zend_language_scanner.c"
 yy526:
 		YYDEBUG(526, *YYCURSOR);
 		yych = *++YYCURSOR;
-		goto yy180;
+		if (yych == '<') goto yy534;
+		goto yy194;
 yy527:
 		YYDEBUG(527, *YYCURSOR);
 		yych = *++YYCURSOR;
-		goto yy178;
+		goto yy181;
 yy528:
 		YYDEBUG(528, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy529;
-		if (yych != 'e') goto yy186;
+		goto yy179;
 yy529:
 		YYDEBUG(529, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy530;
-		if (yych != 'a') goto yy186;
+		if (yych == 'E') goto yy530;
+		if (yych != 'e') goto yy187;
 yy530:
 		YYDEBUG(530, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'K') goto yy531;
-		if (yych != 'k') goto yy186;
+		if (yych == 'A') goto yy531;
+		if (yych != 'a') goto yy187;
 yy531:
 		YYDEBUG(531, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'K') goto yy532;
+		if (yych != 'k') goto yy187;
+yy532:
+		YYDEBUG(532, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(532, *YYCURSOR);
+		YYDEBUG(533, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1130 "Zend/zend_language_scanner.l"
+#line 1134 "Zend/zend_language_scanner.l"
 		{
 	return T_BREAK;
 }
-#line 5527 "Zend/zend_language_scanner.c"
-yy533:
-		YYDEBUG(533, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == '<') goto yy269;
-		goto yy193;
+#line 5535 "Zend/zend_language_scanner.c"
 yy534:
 		YYDEBUG(534, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy541;
-		if (yych == 'a') goto yy541;
-		goto yy186;
+		if (yych == '<') goto yy270;
+		goto yy194;
 yy535:
 		YYDEBUG(535, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy536;
-		if (yych != 'i') goto yy186;
+		if (yych == 'A') goto yy542;
+		if (yych == 'a') goto yy542;
+		goto yy187;
 yy536:
 		YYDEBUG(536, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy537;
-		if (yych != 't') goto yy186;
+		if (yych == 'I') goto yy537;
+		if (yych != 'i') goto yy187;
 yy537:
 		YYDEBUG(537, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy538;
-		if (yych != 'c') goto yy186;
+		if (yych == 'T') goto yy538;
+		if (yych != 't') goto yy187;
 yy538:
 		YYDEBUG(538, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'H') goto yy539;
-		if (yych != 'h') goto yy186;
+		if (yych == 'C') goto yy539;
+		if (yych != 'c') goto yy187;
 yy539:
 		YYDEBUG(539, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'H') goto yy540;
+		if (yych != 'h') goto yy187;
+yy540:
+		YYDEBUG(540, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(540, *YYCURSOR);
+		YYDEBUG(541, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1114 "Zend/zend_language_scanner.l"
+#line 1118 "Zend/zend_language_scanner.l"
 		{
 	return T_SWITCH;
 }
-#line 5571 "Zend/zend_language_scanner.c"
-yy541:
-		YYDEBUG(541, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy542;
-		if (yych != 't') goto yy186;
+#line 5579 "Zend/zend_language_scanner.c"
 yy542:
 		YYDEBUG(542, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy543;
-		if (yych != 'i') goto yy186;
+		if (yych == 'T') goto yy543;
+		if (yych != 't') goto yy187;
 yy543:
 		YYDEBUG(543, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy544;
-		if (yych != 'c') goto yy186;
+		if (yych == 'I') goto yy544;
+		if (yych != 'i') goto yy187;
 yy544:
 		YYDEBUG(544, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'C') goto yy545;
+		if (yych != 'c') goto yy187;
+yy545:
+		YYDEBUG(545, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(545, *YYCURSOR);
+		YYDEBUG(546, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1296 "Zend/zend_language_scanner.l"
+#line 1300 "Zend/zend_language_scanner.l"
 		{
 	return T_STATIC;
 }
-#line 5599 "Zend/zend_language_scanner.c"
-yy546:
-		YYDEBUG(546, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy557;
-		if (yych == 's') goto yy557;
-		goto yy186;
+#line 5607 "Zend/zend_language_scanner.c"
 yy547:
 		YYDEBUG(547, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'D') goto yy555;
-		if (yych == 'd') goto yy555;
-		goto yy186;
+		if (yych == 'S') goto yy558;
+		if (yych == 's') goto yy558;
+		goto yy187;
 yy548:
 		YYDEBUG(548, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy551;
-		if (yych == 'r') goto yy551;
-		goto yy186;
+		if (yych == 'D') goto yy556;
+		if (yych == 'd') goto yy556;
+		goto yy187;
 yy549:
 		YYDEBUG(549, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'R') goto yy552;
+		if (yych == 'r') goto yy552;
+		goto yy187;
+yy550:
+		YYDEBUG(550, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(550, *YYCURSOR);
+		YYDEBUG(551, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1110 "Zend/zend_language_scanner.l"
+#line 1114 "Zend/zend_language_scanner.l"
 		{
 	return T_AS;
 }
-#line 5630 "Zend/zend_language_scanner.c"
-yy551:
-		YYDEBUG(551, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy552;
-		if (yych != 'a') goto yy186;
+#line 5638 "Zend/zend_language_scanner.c"
 yy552:
 		YYDEBUG(552, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'Y') goto yy553;
-		if (yych != 'y') goto yy186;
+		if (yych == 'A') goto yy553;
+		if (yych != 'a') goto yy187;
 yy553:
 		YYDEBUG(553, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'Y') goto yy554;
+		if (yych != 'y') goto yy187;
+yy554:
+		YYDEBUG(554, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(554, *YYCURSOR);
+		YYDEBUG(555, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1332 "Zend/zend_language_scanner.l"
+#line 1336 "Zend/zend_language_scanner.l"
 		{
 	return T_ARRAY;
 }
-#line 5653 "Zend/zend_language_scanner.c"
-yy555:
-		YYDEBUG(555, *YYCURSOR);
+#line 5661 "Zend/zend_language_scanner.c"
+yy556:
+		YYDEBUG(556, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(556, *YYCURSOR);
+		YYDEBUG(557, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1428 "Zend/zend_language_scanner.l"
+#line 1432 "Zend/zend_language_scanner.l"
 		{
 	return T_LOGICAL_AND;
 }
-#line 5666 "Zend/zend_language_scanner.c"
-yy557:
-		YYDEBUG(557, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy558;
-		if (yych != 't') goto yy186;
+#line 5674 "Zend/zend_language_scanner.c"
 yy558:
 		YYDEBUG(558, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy559;
-		if (yych != 'r') goto yy186;
+		if (yych == 'T') goto yy559;
+		if (yych != 't') goto yy187;
 yy559:
 		YYDEBUG(559, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy560;
-		if (yych != 'a') goto yy186;
+		if (yych == 'R') goto yy560;
+		if (yych != 'r') goto yy187;
 yy560:
 		YYDEBUG(560, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy561;
-		if (yych != 'c') goto yy186;
+		if (yych == 'A') goto yy561;
+		if (yych != 'a') goto yy187;
 yy561:
 		YYDEBUG(561, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy562;
-		if (yych != 't') goto yy186;
+		if (yych == 'C') goto yy562;
+		if (yych != 'c') goto yy187;
 yy562:
 		YYDEBUG(562, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy563;
+		if (yych != 't') goto yy187;
+yy563:
+		YYDEBUG(563, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(563, *YYCURSOR);
+		YYDEBUG(564, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1300 "Zend/zend_language_scanner.l"
+#line 1304 "Zend/zend_language_scanner.l"
 		{
 	return T_ABSTRACT;
 }
-#line 5704 "Zend/zend_language_scanner.c"
-yy564:
-		YYDEBUG(564, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy565;
-		if (yych != 'i') goto yy186;
+#line 5712 "Zend/zend_language_scanner.c"
 yy565:
 		YYDEBUG(565, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy566;
-		if (yych != 'l') goto yy186;
+		if (yych == 'I') goto yy566;
+		if (yych != 'i') goto yy187;
 yy566:
 		YYDEBUG(566, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy567;
-		if (yych != 'e') goto yy186;
+		if (yych == 'L') goto yy567;
+		if (yych != 'l') goto yy187;
 yy567:
 		YYDEBUG(567, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'E') goto yy568;
+		if (yych != 'e') goto yy187;
+yy568:
+		YYDEBUG(568, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(568, *YYCURSOR);
+		YYDEBUG(569, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1070 "Zend/zend_language_scanner.l"
+#line 1074 "Zend/zend_language_scanner.l"
 		{
 	return T_WHILE;
 }
-#line 5732 "Zend/zend_language_scanner.c"
-yy569:
-		YYDEBUG(569, *YYCURSOR);
+#line 5740 "Zend/zend_language_scanner.c"
+yy570:
+		YYDEBUG(570, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(570, *YYCURSOR);
+		YYDEBUG(571, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1054 "Zend/zend_language_scanner.l"
+#line 1058 "Zend/zend_language_scanner.l"
 		{
 	return T_IF;
 }
-#line 5745 "Zend/zend_language_scanner.c"
-yy571:
-		YYDEBUG(571, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'P') goto yy613;
-		if (yych == 'p') goto yy613;
-		goto yy186;
+#line 5753 "Zend/zend_language_scanner.c"
 yy572:
 		YYDEBUG(572, *YYCURSOR);
 		yych = *++YYCURSOR;
+		if (yych == 'P') goto yy614;
+		if (yych == 'p') goto yy614;
+		goto yy187;
+yy573:
+		YYDEBUG(573, *YYCURSOR);
+		yych = *++YYCURSOR;
 		if (yych <= 'T') {
 			if (yych <= 'C') {
-				if (yych <= 'B') goto yy186;
-				goto yy580;
+				if (yych <= 'B') goto yy187;
+				goto yy581;
 			} else {
-				if (yych <= 'R') goto yy186;
-				if (yych <= 'S') goto yy578;
-				goto yy579;
+				if (yych <= 'R') goto yy187;
+				if (yych <= 'S') goto yy579;
+				goto yy580;
 			}
 		} else {
 			if (yych <= 'r') {
-				if (yych == 'c') goto yy580;
-				goto yy186;
+				if (yych == 'c') goto yy581;
+				goto yy187;
 			} else {
-				if (yych <= 's') goto yy578;
-				if (yych <= 't') goto yy579;
-				goto yy186;
+				if (yych <= 's') goto yy579;
+				if (yych <= 't') goto yy580;
+				goto yy187;
 			}
 		}
-yy573:
-		YYDEBUG(573, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy574;
-		if (yych != 's') goto yy186;
 yy574:
 		YYDEBUG(574, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy575;
-		if (yych != 'e') goto yy186;
+		if (yych == 'S') goto yy575;
+		if (yych != 's') goto yy187;
 yy575:
 		YYDEBUG(575, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy576;
-		if (yych != 't') goto yy186;
+		if (yych == 'E') goto yy576;
+		if (yych != 'e') goto yy187;
 yy576:
 		YYDEBUG(576, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy577;
+		if (yych != 't') goto yy187;
+yy577:
+		YYDEBUG(577, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(577, *YYCURSOR);
+		YYDEBUG(578, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1284 "Zend/zend_language_scanner.l"
+#line 1288 "Zend/zend_language_scanner.l"
 		{
 	return T_ISSET;
 }
-#line 5801 "Zend/zend_language_scanner.c"
-yy578:
-		YYDEBUG(578, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy599;
-		if (yych == 't') goto yy599;
-		goto yy186;
+#line 5809 "Zend/zend_language_scanner.c"
 yy579:
 		YYDEBUG(579, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy592;
-		if (yych == 'e') goto yy592;
-		goto yy186;
+		if (yych == 'T') goto yy600;
+		if (yych == 't') goto yy600;
+		goto yy187;
 yy580:
 		YYDEBUG(580, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy581;
-		if (yych != 'l') goto yy186;
+		if (yych == 'E') goto yy593;
+		if (yych == 'e') goto yy593;
+		goto yy187;
 yy581:
 		YYDEBUG(581, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'U') goto yy582;
-		if (yych != 'u') goto yy186;
+		if (yych == 'L') goto yy582;
+		if (yych != 'l') goto yy187;
 yy582:
 		YYDEBUG(582, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'D') goto yy583;
-		if (yych != 'd') goto yy186;
+		if (yych == 'U') goto yy583;
+		if (yych != 'u') goto yy187;
 yy583:
 		YYDEBUG(583, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy584;
-		if (yych != 'e') goto yy186;
+		if (yych == 'D') goto yy584;
+		if (yych != 'd') goto yy187;
 yy584:
 		YYDEBUG(584, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'E') goto yy585;
+		if (yych != 'e') goto yy187;
+yy585:
+		YYDEBUG(585, *YYCURSOR);
 		++YYCURSOR;
 		if ((yych = *YYCURSOR) <= '^') {
 			if (yych <= '9') {
-				if (yych >= '0') goto yy185;
+				if (yych >= '0') goto yy186;
 			} else {
-				if (yych <= '@') goto yy585;
-				if (yych <= 'Z') goto yy185;
+				if (yych <= '@') goto yy586;
+				if (yych <= 'Z') goto yy186;
 			}
 		} else {
 			if (yych <= '`') {
-				if (yych <= '_') goto yy586;
+				if (yych <= '_') goto yy587;
 			} else {
-				if (yych <= 'z') goto yy185;
-				if (yych >= 0x7F) goto yy185;
+				if (yych <= 'z') goto yy186;
+				if (yych >= 0x7F) goto yy186;
 			}
 		}
-yy585:
-		YYDEBUG(585, *YYCURSOR);
+yy586:
+		YYDEBUG(586, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1252 "Zend/zend_language_scanner.l"
+#line 1256 "Zend/zend_language_scanner.l"
 		{
 	return T_INCLUDE;
 }
-#line 5859 "Zend/zend_language_scanner.c"
-yy586:
-		YYDEBUG(586, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy587;
-		if (yych != 'o') goto yy186;
+#line 5867 "Zend/zend_language_scanner.c"
 yy587:
 		YYDEBUG(587, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy588;
-		if (yych != 'n') goto yy186;
+		if (yych == 'O') goto yy588;
+		if (yych != 'o') goto yy187;
 yy588:
 		YYDEBUG(588, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy589;
-		if (yych != 'c') goto yy186;
+		if (yych == 'N') goto yy589;
+		if (yych != 'n') goto yy187;
 yy589:
 		YYDEBUG(589, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy590;
-		if (yych != 'e') goto yy186;
+		if (yych == 'C') goto yy590;
+		if (yych != 'c') goto yy187;
 yy590:
 		YYDEBUG(590, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'E') goto yy591;
+		if (yych != 'e') goto yy187;
+yy591:
+		YYDEBUG(591, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(591, *YYCURSOR);
+		YYDEBUG(592, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1256 "Zend/zend_language_scanner.l"
+#line 1260 "Zend/zend_language_scanner.l"
 		{
 	return T_INCLUDE_ONCE;
 }
-#line 5892 "Zend/zend_language_scanner.c"
-yy592:
-		YYDEBUG(592, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy593;
-		if (yych != 'r') goto yy186;
+#line 5900 "Zend/zend_language_scanner.c"
 yy593:
 		YYDEBUG(593, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'F') goto yy594;
-		if (yych != 'f') goto yy186;
+		if (yych == 'R') goto yy594;
+		if (yych != 'r') goto yy187;
 yy594:
 		YYDEBUG(594, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy595;
-		if (yych != 'a') goto yy186;
+		if (yych == 'F') goto yy595;
+		if (yych != 'f') goto yy187;
 yy595:
 		YYDEBUG(595, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy596;
-		if (yych != 'c') goto yy186;
+		if (yych == 'A') goto yy596;
+		if (yych != 'a') goto yy187;
 yy596:
 		YYDEBUG(596, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy597;
-		if (yych != 'e') goto yy186;
+		if (yych == 'C') goto yy597;
+		if (yych != 'c') goto yy187;
 yy597:
 		YYDEBUG(597, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'E') goto yy598;
+		if (yych != 'e') goto yy187;
+yy598:
+		YYDEBUG(598, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(598, *YYCURSOR);
+		YYDEBUG(599, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1154 "Zend/zend_language_scanner.l"
+#line 1158 "Zend/zend_language_scanner.l"
 		{
 	return T_INTERFACE;
 }
-#line 5930 "Zend/zend_language_scanner.c"
-yy599:
-		YYDEBUG(599, *YYCURSOR);
+#line 5938 "Zend/zend_language_scanner.c"
+yy600:
+		YYDEBUG(600, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'E') {
-			if (yych == 'A') goto yy600;
-			if (yych <= 'D') goto yy186;
-			goto yy601;
+			if (yych == 'A') goto yy601;
+			if (yych <= 'D') goto yy187;
+			goto yy602;
 		} else {
 			if (yych <= 'a') {
-				if (yych <= '`') goto yy186;
+				if (yych <= '`') goto yy187;
 			} else {
-				if (yych == 'e') goto yy601;
-				goto yy186;
+				if (yych == 'e') goto yy602;
+				goto yy187;
 			}
 		}
-yy600:
-		YYDEBUG(600, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy607;
-		if (yych == 'n') goto yy607;
-		goto yy186;
 yy601:
 		YYDEBUG(601, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy602;
-		if (yych != 'a') goto yy186;
+		if (yych == 'N') goto yy608;
+		if (yych == 'n') goto yy608;
+		goto yy187;
 yy602:
 		YYDEBUG(602, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'D') goto yy603;
-		if (yych != 'd') goto yy186;
+		if (yych == 'A') goto yy603;
+		if (yych != 'a') goto yy187;
 yy603:
 		YYDEBUG(603, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy604;
-		if (yych != 'o') goto yy186;
+		if (yych == 'D') goto yy604;
+		if (yych != 'd') goto yy187;
 yy604:
 		YYDEBUG(604, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'F') goto yy605;
-		if (yych != 'f') goto yy186;
+		if (yych == 'O') goto yy605;
+		if (yych != 'o') goto yy187;
 yy605:
 		YYDEBUG(605, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'F') goto yy606;
+		if (yych != 'f') goto yy187;
+yy606:
+		YYDEBUG(606, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(606, *YYCURSOR);
+		YYDEBUG(607, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1276 "Zend/zend_language_scanner.l"
+#line 1280 "Zend/zend_language_scanner.l"
 		{
         return T_INSTEADOF;
 }
-#line 5984 "Zend/zend_language_scanner.c"
-yy607:
-		YYDEBUG(607, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy608;
-		if (yych != 'c') goto yy186;
+#line 5992 "Zend/zend_language_scanner.c"
 yy608:
 		YYDEBUG(608, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy609;
-		if (yych != 'e') goto yy186;
+		if (yych == 'C') goto yy609;
+		if (yych != 'c') goto yy187;
 yy609:
 		YYDEBUG(609, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy610;
-		if (yych != 'o') goto yy186;
+		if (yych == 'E') goto yy610;
+		if (yych != 'e') goto yy187;
 yy610:
 		YYDEBUG(610, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'F') goto yy611;
-		if (yych != 'f') goto yy186;
+		if (yych == 'O') goto yy611;
+		if (yych != 'o') goto yy187;
 yy611:
 		YYDEBUG(611, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'F') goto yy612;
+		if (yych != 'f') goto yy187;
+yy612:
+		YYDEBUG(612, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(612, *YYCURSOR);
+		YYDEBUG(613, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1106 "Zend/zend_language_scanner.l"
+#line 1110 "Zend/zend_language_scanner.l"
 		{
 	return T_INSTANCEOF;
 }
-#line 6017 "Zend/zend_language_scanner.c"
-yy613:
-		YYDEBUG(613, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy614;
-		if (yych != 'l') goto yy186;
+#line 6025 "Zend/zend_language_scanner.c"
 yy614:
 		YYDEBUG(614, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy615;
-		if (yych != 'e') goto yy186;
+		if (yych == 'L') goto yy615;
+		if (yych != 'l') goto yy187;
 yy615:
 		YYDEBUG(615, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'M') goto yy616;
-		if (yych != 'm') goto yy186;
+		if (yych == 'E') goto yy616;
+		if (yych != 'e') goto yy187;
 yy616:
 		YYDEBUG(616, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy617;
-		if (yych != 'e') goto yy186;
+		if (yych == 'M') goto yy617;
+		if (yych != 'm') goto yy187;
 yy617:
 		YYDEBUG(617, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy618;
-		if (yych != 'n') goto yy186;
+		if (yych == 'E') goto yy618;
+		if (yych != 'e') goto yy187;
 yy618:
 		YYDEBUG(618, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy619;
-		if (yych != 't') goto yy186;
+		if (yych == 'N') goto yy619;
+		if (yych != 'n') goto yy187;
 yy619:
 		YYDEBUG(619, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy620;
-		if (yych != 's') goto yy186;
+		if (yych == 'T') goto yy620;
+		if (yych != 't') goto yy187;
 yy620:
 		YYDEBUG(620, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'S') goto yy621;
+		if (yych != 's') goto yy187;
+yy621:
+		YYDEBUG(621, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(621, *YYCURSOR);
+		YYDEBUG(622, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1166 "Zend/zend_language_scanner.l"
+#line 1170 "Zend/zend_language_scanner.l"
 		{
 	return T_IMPLEMENTS;
 }
-#line 6065 "Zend/zend_language_scanner.c"
-yy622:
-		YYDEBUG(622, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy630;
-		if (yych == 'r') goto yy630;
-		goto yy186;
+#line 6073 "Zend/zend_language_scanner.c"
 yy623:
 		YYDEBUG(623, *YYCURSOR);
 		yych = *++YYCURSOR;
+		if (yych == 'R') goto yy631;
+		if (yych == 'r') goto yy631;
+		goto yy187;
+yy624:
+		YYDEBUG(624, *YYCURSOR);
+		yych = *++YYCURSOR;
 		if (yych <= 'Y') {
-			if (yych == 'A') goto yy626;
-			if (yych <= 'X') goto yy186;
+			if (yych == 'A') goto yy627;
+			if (yych <= 'X') goto yy187;
 		} else {
 			if (yych <= 'a') {
-				if (yych <= '`') goto yy186;
-				goto yy626;
+				if (yych <= '`') goto yy187;
+				goto yy627;
 			} else {
-				if (yych != 'y') goto yy186;
+				if (yych != 'y') goto yy187;
 			}
 		}
-		YYDEBUG(624, *YYCURSOR);
+		YYDEBUG(625, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(625, *YYCURSOR);
+		YYDEBUG(626, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1038 "Zend/zend_language_scanner.l"
+#line 1042 "Zend/zend_language_scanner.l"
 		{
 	return T_TRY;
 }
-#line 6097 "Zend/zend_language_scanner.c"
-yy626:
-		YYDEBUG(626, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy627;
-		if (yych != 'i') goto yy186;
+#line 6105 "Zend/zend_language_scanner.c"
 yy627:
 		YYDEBUG(627, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy628;
-		if (yych != 't') goto yy186;
+		if (yych == 'I') goto yy628;
+		if (yych != 'i') goto yy187;
 yy628:
 		YYDEBUG(628, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy629;
+		if (yych != 't') goto yy187;
+yy629:
+		YYDEBUG(629, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(629, *YYCURSOR);
+		YYDEBUG(630, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1158 "Zend/zend_language_scanner.l"
+#line 1162 "Zend/zend_language_scanner.l"
 		{
 	return T_TRAIT;
 }
-#line 6120 "Zend/zend_language_scanner.c"
-yy630:
-		YYDEBUG(630, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy631;
-		if (yych != 'o') goto yy186;
+#line 6128 "Zend/zend_language_scanner.c"
 yy631:
 		YYDEBUG(631, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'W') goto yy632;
-		if (yych != 'w') goto yy186;
+		if (yych == 'O') goto yy632;
+		if (yych != 'o') goto yy187;
 yy632:
 		YYDEBUG(632, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'W') goto yy633;
+		if (yych != 'w') goto yy187;
+yy633:
+		YYDEBUG(633, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(633, *YYCURSOR);
+		YYDEBUG(634, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1050 "Zend/zend_language_scanner.l"
+#line 1054 "Zend/zend_language_scanner.l"
 		{
 	return T_THROW;
 }
-#line 6143 "Zend/zend_language_scanner.c"
-yy634:
-		YYDEBUG(634, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych <= 'T') {
-			if (yych == 'Q') goto yy636;
-			if (yych <= 'S') goto yy186;
-		} else {
-			if (yych <= 'q') {
-				if (yych <= 'p') goto yy186;
-				goto yy636;
-			} else {
-				if (yych != 't') goto yy186;
-			}
-		}
+#line 6151 "Zend/zend_language_scanner.c"
+yy635:
 		YYDEBUG(635, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'U') goto yy648;
-		if (yych == 'u') goto yy648;
-		goto yy186;
+		if (yych == 'E') goto yy636;
+		if (yych != 'e') goto yy187;
 yy636:
 		YYDEBUG(636, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'U') goto yy637;
-		if (yych != 'u') goto yy186;
+		if (yych == 'L') goto yy637;
+		if (yych != 'l') goto yy187;
 yy637:
 		YYDEBUG(637, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy638;
-		if (yych != 'i') goto yy186;
+		if (yych == 'D') goto yy638;
+		if (yych != 'd') goto yy187;
 yy638:
 		YYDEBUG(638, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy639;
-		if (yych != 'r') goto yy186;
-yy639:
+		++YYCURSOR;
+		if (yybm[0+(yych = *YYCURSOR)] & 4) {
+			goto yy186;
+		}
 		YYDEBUG(639, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy640;
-		if (yych != 'e') goto yy186;
+		yyleng = YYCURSOR - SCNG(yy_text);
+#line 1038 "Zend/zend_language_scanner.l"
+		{
+	return T_YIELD;
+}
+#line 6179 "Zend/zend_language_scanner.c"
 yy640:
 		YYDEBUG(640, *YYCURSOR);
-		++YYCURSOR;
-		if ((yych = *YYCURSOR) <= '^') {
-			if (yych <= '9') {
-				if (yych >= '0') goto yy185;
-			} else {
-				if (yych <= '@') goto yy641;
-				if (yych <= 'Z') goto yy185;
-			}
+		yych = *++YYCURSOR;
+		if (yych <= 'T') {
+			if (yych == 'Q') goto yy642;
+			if (yych <= 'S') goto yy187;
 		} else {
-			if (yych <= '`') {
-				if (yych <= '_') goto yy642;
+			if (yych <= 'q') {
+				if (yych <= 'p') goto yy187;
+				goto yy642;
 			} else {
-				if (yych <= 'z') goto yy185;
-				if (yych >= 0x7F) goto yy185;
+				if (yych != 't') goto yy187;
 			}
 		}
-yy641:
 		YYDEBUG(641, *YYCURSOR);
-		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1260 "Zend/zend_language_scanner.l"
-		{
-	return T_REQUIRE;
-}
-#line 6208 "Zend/zend_language_scanner.c"
+		yych = *++YYCURSOR;
+		if (yych == 'U') goto yy654;
+		if (yych == 'u') goto yy654;
+		goto yy187;
 yy642:
 		YYDEBUG(642, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy643;
-		if (yych != 'o') goto yy186;
+		if (yych == 'U') goto yy643;
+		if (yych != 'u') goto yy187;
 yy643:
 		YYDEBUG(643, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy644;
-		if (yych != 'n') goto yy186;
+		if (yych == 'I') goto yy644;
+		if (yych != 'i') goto yy187;
 yy644:
 		YYDEBUG(644, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy645;
-		if (yych != 'c') goto yy186;
+		if (yych == 'R') goto yy645;
+		if (yych != 'r') goto yy187;
 yy645:
 		YYDEBUG(645, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych == 'E') goto yy646;
-		if (yych != 'e') goto yy186;
+		if (yych != 'e') goto yy187;
 yy646:
 		YYDEBUG(646, *YYCURSOR);
 		++YYCURSOR;
-		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+		if ((yych = *YYCURSOR) <= '^') {
+			if (yych <= '9') {
+				if (yych >= '0') goto yy186;
+			} else {
+				if (yych <= '@') goto yy647;
+				if (yych <= 'Z') goto yy186;
+			}
+		} else {
+			if (yych <= '`') {
+				if (yych <= '_') goto yy648;
+			} else {
+				if (yych <= 'z') goto yy186;
+				if (yych >= 0x7F) goto yy186;
+			}
 		}
+yy647:
 		YYDEBUG(647, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
 #line 1264 "Zend/zend_language_scanner.l"
 		{
-	return T_REQUIRE_ONCE;
+	return T_REQUIRE;
 }
-#line 6241 "Zend/zend_language_scanner.c"
+#line 6244 "Zend/zend_language_scanner.c"
 yy648:
 		YYDEBUG(648, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy649;
-		if (yych != 'r') goto yy186;
+		if (yych == 'O') goto yy649;
+		if (yych != 'o') goto yy187;
 yy649:
 		YYDEBUG(649, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych == 'N') goto yy650;
-		if (yych != 'n') goto yy186;
+		if (yych != 'n') goto yy187;
 yy650:
 		YYDEBUG(650, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'C') goto yy651;
+		if (yych != 'c') goto yy187;
+yy651:
+		YYDEBUG(651, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'E') goto yy652;
+		if (yych != 'e') goto yy187;
+yy652:
+		YYDEBUG(652, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(651, *YYCURSOR);
+		YYDEBUG(653, *YYCURSOR);
+		yyleng = YYCURSOR - SCNG(yy_text);
+#line 1268 "Zend/zend_language_scanner.l"
+		{
+	return T_REQUIRE_ONCE;
+}
+#line 6277 "Zend/zend_language_scanner.c"
+yy654:
+		YYDEBUG(654, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'R') goto yy655;
+		if (yych != 'r') goto yy187;
+yy655:
+		YYDEBUG(655, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'N') goto yy656;
+		if (yych != 'n') goto yy187;
+yy656:
+		YYDEBUG(656, *YYCURSOR);
+		++YYCURSOR;
+		if (yybm[0+(yych = *YYCURSOR)] & 4) {
+			goto yy186;
+		}
+		YYDEBUG(657, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
 #line 1034 "Zend/zend_language_scanner.l"
 		{
 	return T_RETURN;
 }
-#line 6264 "Zend/zend_language_scanner.c"
-yy652:
-		YYDEBUG(652, *YYCURSOR);
+#line 6300 "Zend/zend_language_scanner.c"
+yy658:
+		YYDEBUG(658, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'T') {
 			if (yych <= 'L') {
-				if (yych <= 'K') goto yy186;
-				goto yy675;
+				if (yych <= 'K') goto yy187;
+				goto yy681;
 			} else {
-				if (yych <= 'R') goto yy186;
-				if (yych <= 'S') goto yy674;
-				goto yy673;
+				if (yych <= 'R') goto yy187;
+				if (yych <= 'S') goto yy680;
+				goto yy679;
 			}
 		} else {
 			if (yych <= 'r') {
-				if (yych == 'l') goto yy675;
-				goto yy186;
+				if (yych == 'l') goto yy681;
+				goto yy187;
 			} else {
-				if (yych <= 's') goto yy674;
-				if (yych <= 't') goto yy673;
-				goto yy186;
+				if (yych <= 's') goto yy680;
+				if (yych <= 't') goto yy679;
+				goto yy187;
 			}
 		}
-yy653:
-		YYDEBUG(653, *YYCURSOR);
+yy659:
+		YYDEBUG(659, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'O') {
-			if (yych == 'A') goto yy665;
-			if (yych <= 'N') goto yy186;
-			goto yy666;
+			if (yych == 'A') goto yy671;
+			if (yych <= 'N') goto yy187;
+			goto yy672;
 		} else {
 			if (yych <= 'a') {
-				if (yych <= '`') goto yy186;
-				goto yy665;
+				if (yych <= '`') goto yy187;
+				goto yy671;
 			} else {
-				if (yych == 'o') goto yy666;
-				goto yy186;
+				if (yych == 'o') goto yy672;
+				goto yy187;
 			}
 		}
-yy654:
-		YYDEBUG(654, *YYCURSOR);
+yy660:
+		YYDEBUG(660, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy655;
-		if (yych != 'n') goto yy186;
-yy655:
-		YYDEBUG(655, *YYCURSOR);
+		if (yych == 'N') goto yy661;
+		if (yych != 'n') goto yy187;
+yy661:
+		YYDEBUG(661, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'T') {
-			if (yych <= 'R') goto yy186;
-			if (yych >= 'T') goto yy657;
+			if (yych <= 'R') goto yy187;
+			if (yych >= 'T') goto yy663;
 		} else {
-			if (yych <= 'r') goto yy186;
-			if (yych <= 's') goto yy656;
-			if (yych <= 't') goto yy657;
-			goto yy186;
+			if (yych <= 'r') goto yy187;
+			if (yych <= 's') goto yy662;
+			if (yych <= 't') goto yy663;
+			goto yy187;
 		}
-yy656:
-		YYDEBUG(656, *YYCURSOR);
+yy662:
+		YYDEBUG(662, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy663;
-		if (yych == 't') goto yy663;
-		goto yy186;
-yy657:
-		YYDEBUG(657, *YYCURSOR);
+		if (yych == 'T') goto yy669;
+		if (yych == 't') goto yy669;
+		goto yy187;
+yy663:
+		YYDEBUG(663, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy658;
-		if (yych != 'i') goto yy186;
-yy658:
-		YYDEBUG(658, *YYCURSOR);
+		if (yych == 'I') goto yy664;
+		if (yych != 'i') goto yy187;
+yy664:
+		YYDEBUG(664, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy659;
-		if (yych != 'n') goto yy186;
-yy659:
-		YYDEBUG(659, *YYCURSOR);
+		if (yych == 'N') goto yy665;
+		if (yych != 'n') goto yy187;
+yy665:
+		YYDEBUG(665, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'U') goto yy660;
-		if (yych != 'u') goto yy186;
-yy660:
-		YYDEBUG(660, *YYCURSOR);
+		if (yych == 'U') goto yy666;
+		if (yych != 'u') goto yy187;
+yy666:
+		YYDEBUG(666, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy661;
-		if (yych != 'e') goto yy186;
-yy661:
-		YYDEBUG(661, *YYCURSOR);
+		if (yych == 'E') goto yy667;
+		if (yych != 'e') goto yy187;
+yy667:
+		YYDEBUG(667, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(662, *YYCURSOR);
+		YYDEBUG(668, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1134 "Zend/zend_language_scanner.l"
+#line 1138 "Zend/zend_language_scanner.l"
 		{
 	return T_CONTINUE;
 }
-#line 6358 "Zend/zend_language_scanner.c"
-yy663:
-		YYDEBUG(663, *YYCURSOR);
+#line 6394 "Zend/zend_language_scanner.c"
+yy669:
+		YYDEBUG(669, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(664, *YYCURSOR);
+		YYDEBUG(670, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
 #line 1030 "Zend/zend_language_scanner.l"
 		{
 	return T_CONST;
 }
-#line 6371 "Zend/zend_language_scanner.c"
-yy665:
-		YYDEBUG(665, *YYCURSOR);
+#line 6407 "Zend/zend_language_scanner.c"
+yy671:
+		YYDEBUG(671, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy670;
-		if (yych == 's') goto yy670;
-		goto yy186;
-yy666:
-		YYDEBUG(666, *YYCURSOR);
+		if (yych == 'S') goto yy676;
+		if (yych == 's') goto yy676;
+		goto yy187;
+yy672:
+		YYDEBUG(672, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy667;
-		if (yych != 'n') goto yy186;
-yy667:
-		YYDEBUG(667, *YYCURSOR);
+		if (yych == 'N') goto yy673;
+		if (yych != 'n') goto yy187;
+yy673:
+		YYDEBUG(673, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy668;
-		if (yych != 'e') goto yy186;
-yy668:
-		YYDEBUG(668, *YYCURSOR);
+		if (yych == 'E') goto yy674;
+		if (yych != 'e') goto yy187;
+yy674:
+		YYDEBUG(674, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(669, *YYCURSOR);
+		YYDEBUG(675, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1212 "Zend/zend_language_scanner.l"
+#line 1216 "Zend/zend_language_scanner.l"
 		{
 	return T_CLONE;
 }
-#line 6400 "Zend/zend_language_scanner.c"
-yy670:
-		YYDEBUG(670, *YYCURSOR);
+#line 6436 "Zend/zend_language_scanner.c"
+yy676:
+		YYDEBUG(676, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy671;
-		if (yych != 's') goto yy186;
-yy671:
-		YYDEBUG(671, *YYCURSOR);
+		if (yych == 'S') goto yy677;
+		if (yych != 's') goto yy187;
+yy677:
+		YYDEBUG(677, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(672, *YYCURSOR);
+		YYDEBUG(678, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1150 "Zend/zend_language_scanner.l"
+#line 1154 "Zend/zend_language_scanner.l"
 		{
 	return T_CLASS;
 }
-#line 6418 "Zend/zend_language_scanner.c"
-yy673:
-		YYDEBUG(673, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy684;
-		if (yych == 'c') goto yy684;
-		goto yy186;
-yy674:
-		YYDEBUG(674, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy682;
-		if (yych == 'e') goto yy682;
-		goto yy186;
-yy675:
-		YYDEBUG(675, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy676;
-		if (yych != 'l') goto yy186;
-yy676:
-		YYDEBUG(676, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy677;
-		if (yych != 'a') goto yy186;
-yy677:
-		YYDEBUG(677, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'B') goto yy678;
-		if (yych != 'b') goto yy186;
-yy678:
-		YYDEBUG(678, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy679;
-		if (yych != 'l') goto yy186;
+#line 6454 "Zend/zend_language_scanner.c"
 yy679:
 		YYDEBUG(679, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy680;
-		if (yych != 'e') goto yy186;
+		if (yych == 'C') goto yy690;
+		if (yych == 'c') goto yy690;
+		goto yy187;
 yy680:
 		YYDEBUG(680, *YYCURSOR);
-		++YYCURSOR;
-		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
-		}
+		yych = *++YYCURSOR;
+		if (yych == 'E') goto yy688;
+		if (yych == 'e') goto yy688;
+		goto yy187;
+yy681:
 		YYDEBUG(681, *YYCURSOR);
-		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1336 "Zend/zend_language_scanner.l"
-		{
- return T_CALLABLE;
-}
-#line 6468 "Zend/zend_language_scanner.c"
+		yych = *++YYCURSOR;
+		if (yych == 'L') goto yy682;
+		if (yych != 'l') goto yy187;
 yy682:
 		YYDEBUG(682, *YYCURSOR);
-		++YYCURSOR;
-		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
-		}
+		yych = *++YYCURSOR;
+		if (yych == 'A') goto yy683;
+		if (yych != 'a') goto yy187;
+yy683:
 		YYDEBUG(683, *YYCURSOR);
-		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1122 "Zend/zend_language_scanner.l"
-		{
-	return T_CASE;
-}
-#line 6481 "Zend/zend_language_scanner.c"
+		yych = *++YYCURSOR;
+		if (yych == 'B') goto yy684;
+		if (yych != 'b') goto yy187;
 yy684:
 		YYDEBUG(684, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'H') goto yy685;
-		if (yych != 'h') goto yy186;
+		if (yych == 'L') goto yy685;
+		if (yych != 'l') goto yy187;
 yy685:
 		YYDEBUG(685, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'E') goto yy686;
+		if (yych != 'e') goto yy187;
+yy686:
+		YYDEBUG(686, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(686, *YYCURSOR);
+		YYDEBUG(687, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1042 "Zend/zend_language_scanner.l"
+#line 1340 "Zend/zend_language_scanner.l"
 		{
-	return T_CATCH;
+ return T_CALLABLE;
 }
-#line 6499 "Zend/zend_language_scanner.c"
-yy687:
-		YYDEBUG(687, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy704;
-		if (yych == 'n') goto yy704;
-		goto yy186;
+#line 6504 "Zend/zend_language_scanner.c"
 yy688:
 		YYDEBUG(688, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy697;
-		if (yych == 'r') goto yy697;
-		goto yy186;
-yy689:
+		++YYCURSOR;
+		if (yybm[0+(yych = *YYCURSOR)] & 4) {
+			goto yy186;
+		}
 		YYDEBUG(689, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy690;
-		if (yych != 'n') goto yy186;
+		yyleng = YYCURSOR - SCNG(yy_text);
+#line 1126 "Zend/zend_language_scanner.l"
+		{
+	return T_CASE;
+}
+#line 6517 "Zend/zend_language_scanner.c"
 yy690:
 		YYDEBUG(690, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy691;
-		if (yych != 'c') goto yy186;
+		if (yych == 'H') goto yy691;
+		if (yych != 'h') goto yy187;
 yy691:
 		YYDEBUG(691, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy692;
-		if (yych != 't') goto yy186;
-yy692:
+		++YYCURSOR;
+		if (yybm[0+(yych = *YYCURSOR)] & 4) {
+			goto yy186;
+		}
 		YYDEBUG(692, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy693;
-		if (yych != 'i') goto yy186;
+		yyleng = YYCURSOR - SCNG(yy_text);
+#line 1046 "Zend/zend_language_scanner.l"
+		{
+	return T_CATCH;
+}
+#line 6535 "Zend/zend_language_scanner.c"
 yy693:
 		YYDEBUG(693, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy694;
-		if (yych != 'o') goto yy186;
+		if (yych == 'N') goto yy710;
+		if (yych == 'n') goto yy710;
+		goto yy187;
 yy694:
 		YYDEBUG(694, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy695;
-		if (yych != 'n') goto yy186;
+		if (yych == 'R') goto yy703;
+		if (yych == 'r') goto yy703;
+		goto yy187;
 yy695:
 		YYDEBUG(695, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'N') goto yy696;
+		if (yych != 'n') goto yy187;
+yy696:
+		YYDEBUG(696, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'C') goto yy697;
+		if (yych != 'c') goto yy187;
+yy697:
+		YYDEBUG(697, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy698;
+		if (yych != 't') goto yy187;
+yy698:
+		YYDEBUG(698, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'I') goto yy699;
+		if (yych != 'i') goto yy187;
+yy699:
+		YYDEBUG(699, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'O') goto yy700;
+		if (yych != 'o') goto yy187;
+yy700:
+		YYDEBUG(700, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'N') goto yy701;
+		if (yych != 'n') goto yy187;
+yy701:
+		YYDEBUG(701, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(696, *YYCURSOR);
+		YYDEBUG(702, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
 #line 1026 "Zend/zend_language_scanner.l"
 		{
 	return T_FUNCTION;
 }
-#line 6554 "Zend/zend_language_scanner.c"
-yy697:
-		YYDEBUG(697, *YYCURSOR);
+#line 6590 "Zend/zend_language_scanner.c"
+yy703:
+		YYDEBUG(703, *YYCURSOR);
 		++YYCURSOR;
 		if ((yych = *YYCURSOR) <= '^') {
 			if (yych <= '@') {
-				if (yych <= '/') goto yy698;
-				if (yych <= '9') goto yy185;
+				if (yych <= '/') goto yy704;
+				if (yych <= '9') goto yy186;
 			} else {
-				if (yych == 'E') goto yy699;
-				if (yych <= 'Z') goto yy185;
+				if (yych == 'E') goto yy705;
+				if (yych <= 'Z') goto yy186;
 			}
 		} else {
 			if (yych <= 'd') {
-				if (yych != '`') goto yy185;
+				if (yych != '`') goto yy186;
 			} else {
-				if (yych <= 'e') goto yy699;
-				if (yych <= 'z') goto yy185;
-				if (yych >= 0x7F) goto yy185;
+				if (yych <= 'e') goto yy705;
+				if (yych <= 'z') goto yy186;
+				if (yych >= 0x7F) goto yy186;
 			}
 		}
-yy698:
-		YYDEBUG(698, *YYCURSOR);
+yy704:
+		YYDEBUG(704, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1082 "Zend/zend_language_scanner.l"
+#line 1086 "Zend/zend_language_scanner.l"
 		{
 	return T_FOR;
 }
-#line 6582 "Zend/zend_language_scanner.c"
-yy699:
-		YYDEBUG(699, *YYCURSOR);
+#line 6618 "Zend/zend_language_scanner.c"
+yy705:
+		YYDEBUG(705, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy700;
-		if (yych != 'a') goto yy186;
-yy700:
-		YYDEBUG(700, *YYCURSOR);
+		if (yych == 'A') goto yy706;
+		if (yych != 'a') goto yy187;
+yy706:
+		YYDEBUG(706, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy701;
-		if (yych != 'c') goto yy186;
-yy701:
-		YYDEBUG(701, *YYCURSOR);
+		if (yych == 'C') goto yy707;
+		if (yych != 'c') goto yy187;
+yy707:
+		YYDEBUG(707, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'H') goto yy702;
-		if (yych != 'h') goto yy186;
-yy702:
-		YYDEBUG(702, *YYCURSOR);
+		if (yych == 'H') goto yy708;
+		if (yych != 'h') goto yy187;
+yy708:
+		YYDEBUG(708, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(703, *YYCURSOR);
+		YYDEBUG(709, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1090 "Zend/zend_language_scanner.l"
+#line 1094 "Zend/zend_language_scanner.l"
 		{
 	return T_FOREACH;
 }
-#line 6610 "Zend/zend_language_scanner.c"
-yy704:
-		YYDEBUG(704, *YYCURSOR);
+#line 6646 "Zend/zend_language_scanner.c"
+yy710:
+		YYDEBUG(710, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy705;
-		if (yych != 'a') goto yy186;
-yy705:
-		YYDEBUG(705, *YYCURSOR);
+		if (yych == 'A') goto yy711;
+		if (yych != 'a') goto yy187;
+yy711:
+		YYDEBUG(711, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy706;
-		if (yych != 'l') goto yy186;
-yy706:
-		YYDEBUG(706, *YYCURSOR);
+		if (yych == 'L') goto yy712;
+		if (yych != 'l') goto yy187;
+yy712:
+		YYDEBUG(712, *YYCURSOR);
 		++YYCURSOR;
 		if ((yych = *YYCURSOR) <= '^') {
 			if (yych <= '@') {
-				if (yych <= '/') goto yy707;
-				if (yych <= '9') goto yy185;
+				if (yych <= '/') goto yy713;
+				if (yych <= '9') goto yy186;
 			} else {
-				if (yych == 'L') goto yy708;
-				if (yych <= 'Z') goto yy185;
+				if (yych == 'L') goto yy714;
+				if (yych <= 'Z') goto yy186;
 			}
 		} else {
 			if (yych <= 'k') {
-				if (yych != '`') goto yy185;
+				if (yych != '`') goto yy186;
 			} else {
-				if (yych <= 'l') goto yy708;
-				if (yych <= 'z') goto yy185;
-				if (yych >= 0x7F) goto yy185;
+				if (yych <= 'l') goto yy714;
+				if (yych <= 'z') goto yy186;
+				if (yych >= 0x7F) goto yy186;
 			}
 		}
-yy707:
-		YYDEBUG(707, *YYCURSOR);
+yy713:
+		YYDEBUG(713, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1304 "Zend/zend_language_scanner.l"
+#line 1308 "Zend/zend_language_scanner.l"
 		{
 	return T_FINAL;
 }
-#line 6648 "Zend/zend_language_scanner.c"
-yy708:
-		YYDEBUG(708, *YYCURSOR);
+#line 6684 "Zend/zend_language_scanner.c"
+yy714:
+		YYDEBUG(714, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'Y') goto yy709;
-		if (yych != 'y') goto yy186;
-yy709:
-		YYDEBUG(709, *YYCURSOR);
+		if (yych == 'Y') goto yy715;
+		if (yych != 'y') goto yy187;
+yy715:
+		YYDEBUG(715, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(710, *YYCURSOR);
+		YYDEBUG(716, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1046 "Zend/zend_language_scanner.l"
+#line 1050 "Zend/zend_language_scanner.l"
 		{
 	return T_FINALLY;
 }
-#line 6666 "Zend/zend_language_scanner.c"
-yy711:
-		YYDEBUG(711, *YYCURSOR);
+#line 6702 "Zend/zend_language_scanner.c"
+yy717:
+		YYDEBUG(717, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych <= 'F') {
-			if (yych == 'C') goto yy717;
-			if (yych <= 'E') goto yy186;
-			goto yy718;
+			if (yych == 'C') goto yy723;
+			if (yych <= 'E') goto yy187;
+			goto yy724;
 		} else {
 			if (yych <= 'c') {
-				if (yych <= 'b') goto yy186;
-				goto yy717;
+				if (yych <= 'b') goto yy187;
+				goto yy723;
 			} else {
-				if (yych == 'f') goto yy718;
-				goto yy186;
+				if (yych == 'f') goto yy724;
+				goto yy187;
 			}
 		}
-yy712:
-		YYDEBUG(712, *YYCURSOR);
+yy718:
+		YYDEBUG(718, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy715;
-		if (yych == 'e') goto yy715;
-		goto yy186;
-yy713:
-		YYDEBUG(713, *YYCURSOR);
+		if (yych == 'E') goto yy721;
+		if (yych == 'e') goto yy721;
+		goto yy187;
+yy719:
+		YYDEBUG(719, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(714, *YYCURSOR);
+		YYDEBUG(720, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1078 "Zend/zend_language_scanner.l"
+#line 1082 "Zend/zend_language_scanner.l"
 		{
 	return T_DO;
 }
-#line 6701 "Zend/zend_language_scanner.c"
-yy715:
-		YYDEBUG(715, *YYCURSOR);
+#line 6737 "Zend/zend_language_scanner.c"
+yy721:
+		YYDEBUG(721, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(716, *YYCURSOR);
+		YYDEBUG(722, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
 #line 1022 "Zend/zend_language_scanner.l"
 		{
 	return T_EXIT;
 }
-#line 6714 "Zend/zend_language_scanner.c"
-yy717:
-		YYDEBUG(717, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy724;
-		if (yych == 'l') goto yy724;
-		goto yy186;
-yy718:
-		YYDEBUG(718, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy719;
-		if (yych != 'a') goto yy186;
-yy719:
-		YYDEBUG(719, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'U') goto yy720;
-		if (yych != 'u') goto yy186;
-yy720:
-		YYDEBUG(720, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy721;
-		if (yych != 'l') goto yy186;
-yy721:
-		YYDEBUG(721, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy722;
-		if (yych != 't') goto yy186;
-yy722:
-		YYDEBUG(722, *YYCURSOR);
-		++YYCURSOR;
-		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
-		}
+#line 6750 "Zend/zend_language_scanner.c"
+yy723:
 		YYDEBUG(723, *YYCURSOR);
-		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1126 "Zend/zend_language_scanner.l"
-		{
-	return T_DEFAULT;
-}
-#line 6753 "Zend/zend_language_scanner.c"
+		yych = *++YYCURSOR;
+		if (yych == 'L') goto yy730;
+		if (yych == 'l') goto yy730;
+		goto yy187;
 yy724:
 		YYDEBUG(724, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yych == 'A') goto yy725;
-		if (yych != 'a') goto yy186;
+		if (yych != 'a') goto yy187;
 yy725:
 		YYDEBUG(725, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy726;
-		if (yych != 'r') goto yy186;
+		if (yych == 'U') goto yy726;
+		if (yych != 'u') goto yy187;
 yy726:
 		YYDEBUG(726, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy727;
-		if (yych != 'e') goto yy186;
+		if (yych == 'L') goto yy727;
+		if (yych != 'l') goto yy187;
 yy727:
 		YYDEBUG(727, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy728;
+		if (yych != 't') goto yy187;
+yy728:
+		YYDEBUG(728, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(728, *YYCURSOR);
+		YYDEBUG(729, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1098 "Zend/zend_language_scanner.l"
+#line 1130 "Zend/zend_language_scanner.l"
 		{
-	return T_DECLARE;
+	return T_DEFAULT;
 }
-#line 6781 "Zend/zend_language_scanner.c"
-yy729:
-		YYDEBUG(729, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'H') goto yy791;
-		if (yych == 'h') goto yy791;
-		goto yy186;
+#line 6789 "Zend/zend_language_scanner.c"
 yy730:
 		YYDEBUG(730, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy785;
-		if (yych == 's') goto yy785;
-		goto yy186;
+		if (yych == 'A') goto yy731;
+		if (yych != 'a') goto yy187;
 yy731:
 		YYDEBUG(731, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'P') goto yy781;
-		if (yych == 'p') goto yy781;
-		goto yy186;
+		if (yych == 'R') goto yy732;
+		if (yych != 'r') goto yy187;
 yy732:
 		YYDEBUG(732, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'D') goto yy747;
-		if (yych == 'd') goto yy747;
-		goto yy186;
+		if (yych == 'E') goto yy733;
+		if (yych != 'e') goto yy187;
 yy733:
 		YYDEBUG(733, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy744;
-		if (yych == 'a') goto yy744;
-		goto yy186;
-yy734:
-		YYDEBUG(734, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych <= 'T') {
-			if (yych == 'I') goto yy735;
-			if (yych <= 'S') goto yy186;
-			goto yy736;
-		} else {
-			if (yych <= 'i') {
-				if (yych <= 'h') goto yy186;
-			} else {
-				if (yych == 't') goto yy736;
-				goto yy186;
-			}
+		++YYCURSOR;
+		if (yybm[0+(yych = *YYCURSOR)] & 4) {
+			goto yy186;
 		}
+		YYDEBUG(734, *YYCURSOR);
+		yyleng = YYCURSOR - SCNG(yy_text);
+#line 1102 "Zend/zend_language_scanner.l"
+		{
+	return T_DECLARE;
+}
+#line 6817 "Zend/zend_language_scanner.c"
 yy735:
 		YYDEBUG(735, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy742;
-		if (yych == 't') goto yy742;
-		goto yy186;
+		if (yych == 'H') goto yy797;
+		if (yych == 'h') goto yy797;
+		goto yy187;
 yy736:
 		YYDEBUG(736, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy737;
-		if (yych != 'e') goto yy186;
+		if (yych == 'S') goto yy791;
+		if (yych == 's') goto yy791;
+		goto yy187;
 yy737:
 		YYDEBUG(737, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'N') goto yy738;
-		if (yych != 'n') goto yy186;
+		if (yych == 'P') goto yy787;
+		if (yych == 'p') goto yy787;
+		goto yy187;
 yy738:
 		YYDEBUG(738, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'D') goto yy739;
-		if (yych != 'd') goto yy186;
+		if (yych == 'D') goto yy753;
+		if (yych == 'd') goto yy753;
+		goto yy187;
 yy739:
 		YYDEBUG(739, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'S') goto yy740;
-		if (yych != 's') goto yy186;
+		if (yych == 'A') goto yy750;
+		if (yych == 'a') goto yy750;
+		goto yy187;
 yy740:
 		YYDEBUG(740, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych <= 'T') {
+			if (yych == 'I') goto yy741;
+			if (yych <= 'S') goto yy187;
+			goto yy742;
+		} else {
+			if (yych <= 'i') {
+				if (yych <= 'h') goto yy187;
+			} else {
+				if (yych == 't') goto yy742;
+				goto yy187;
+			}
+		}
+yy741:
+		YYDEBUG(741, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy748;
+		if (yych == 't') goto yy748;
+		goto yy187;
+yy742:
+		YYDEBUG(742, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'E') goto yy743;
+		if (yych != 'e') goto yy187;
+yy743:
+		YYDEBUG(743, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'N') goto yy744;
+		if (yych != 'n') goto yy187;
+yy744:
+		YYDEBUG(744, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'D') goto yy745;
+		if (yych != 'd') goto yy187;
+yy745:
+		YYDEBUG(745, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'S') goto yy746;
+		if (yych != 's') goto yy187;
+yy746:
+		YYDEBUG(746, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(741, *YYCURSOR);
+		YYDEBUG(747, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1162 "Zend/zend_language_scanner.l"
+#line 1166 "Zend/zend_language_scanner.l"
 		{
 	return T_EXTENDS;
 }
-#line 6865 "Zend/zend_language_scanner.c"
-yy742:
-		YYDEBUG(742, *YYCURSOR);
+#line 6901 "Zend/zend_language_scanner.c"
+yy748:
+		YYDEBUG(748, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(743, *YYCURSOR);
+		YYDEBUG(749, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
 #line 1018 "Zend/zend_language_scanner.l"
 		{
 	return T_EXIT;
 }
-#line 6878 "Zend/zend_language_scanner.c"
-yy744:
-		YYDEBUG(744, *YYCURSOR);
+#line 6914 "Zend/zend_language_scanner.c"
+yy750:
+		YYDEBUG(750, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy745;
-		if (yych != 'l') goto yy186;
-yy745:
-		YYDEBUG(745, *YYCURSOR);
+		if (yych == 'L') goto yy751;
+		if (yych != 'l') goto yy187;
+yy751:
+		YYDEBUG(751, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(746, *YYCURSOR);
+		YYDEBUG(752, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1248 "Zend/zend_language_scanner.l"
+#line 1252 "Zend/zend_language_scanner.l"
 		{
 	return T_EVAL;
 }
-#line 6896 "Zend/zend_language_scanner.c"
-yy747:
-		YYDEBUG(747, *YYCURSOR);
+#line 6932 "Zend/zend_language_scanner.c"
+yy753:
+		YYDEBUG(753, *YYCURSOR);
 		yych = *++YYCURSOR;
 		YYDEBUG(-1, yych);
 		switch (yych) {
 		case 'D':
-		case 'd':	goto yy748;
+		case 'd':	goto yy754;
 		case 'F':
-		case 'f':	goto yy749;
+		case 'f':	goto yy755;
 		case 'I':
-		case 'i':	goto yy750;
+		case 'i':	goto yy756;
 		case 'S':
-		case 's':	goto yy751;
+		case 's':	goto yy757;
 		case 'W':
-		case 'w':	goto yy752;
-		default:	goto yy186;
+		case 'w':	goto yy758;
+		default:	goto yy187;
 		}
-yy748:
-		YYDEBUG(748, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy774;
-		if (yych == 'e') goto yy774;
-		goto yy186;
-yy749:
-		YYDEBUG(749, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy766;
-		if (yych == 'o') goto yy766;
-		goto yy186;
-yy750:
-		YYDEBUG(750, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'F') goto yy764;
-		if (yych == 'f') goto yy764;
-		goto yy186;
-yy751:
-		YYDEBUG(751, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'W') goto yy758;
-		if (yych == 'w') goto yy758;
-		goto yy186;
-yy752:
-		YYDEBUG(752, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'H') goto yy753;
-		if (yych != 'h') goto yy186;
-yy753:
-		YYDEBUG(753, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy754;
-		if (yych != 'i') goto yy186;
 yy754:
 		YYDEBUG(754, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy755;
-		if (yych != 'l') goto yy186;
+		if (yych == 'E') goto yy780;
+		if (yych == 'e') goto yy780;
+		goto yy187;
 yy755:
 		YYDEBUG(755, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy756;
-		if (yych != 'e') goto yy186;
+		if (yych == 'O') goto yy772;
+		if (yych == 'o') goto yy772;
+		goto yy187;
 yy756:
 		YYDEBUG(756, *YYCURSOR);
-		++YYCURSOR;
-		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
-		}
+		yych = *++YYCURSOR;
+		if (yych == 'F') goto yy770;
+		if (yych == 'f') goto yy770;
+		goto yy187;
+yy757:
 		YYDEBUG(757, *YYCURSOR);
-		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1074 "Zend/zend_language_scanner.l"
-		{
-	return T_ENDWHILE;
-}
-#line 6970 "Zend/zend_language_scanner.c"
+		yych = *++YYCURSOR;
+		if (yych == 'W') goto yy764;
+		if (yych == 'w') goto yy764;
+		goto yy187;
 yy758:
 		YYDEBUG(758, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'I') goto yy759;
-		if (yych != 'i') goto yy186;
+		if (yych == 'H') goto yy759;
+		if (yych != 'h') goto yy187;
 yy759:
 		YYDEBUG(759, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy760;
-		if (yych != 't') goto yy186;
+		if (yych == 'I') goto yy760;
+		if (yych != 'i') goto yy187;
 yy760:
 		YYDEBUG(760, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy761;
-		if (yych != 'c') goto yy186;
+		if (yych == 'L') goto yy761;
+		if (yych != 'l') goto yy187;
 yy761:
 		YYDEBUG(761, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'H') goto yy762;
-		if (yych != 'h') goto yy186;
+		if (yych == 'E') goto yy762;
+		if (yych != 'e') goto yy187;
 yy762:
 		YYDEBUG(762, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
 		YYDEBUG(763, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1118 "Zend/zend_language_scanner.l"
+#line 1078 "Zend/zend_language_scanner.l"
 		{
-	return T_ENDSWITCH;
+	return T_ENDWHILE;
 }
-#line 7003 "Zend/zend_language_scanner.c"
+#line 7006 "Zend/zend_language_scanner.c"
 yy764:
 		YYDEBUG(764, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'I') goto yy765;
+		if (yych != 'i') goto yy187;
+yy765:
+		YYDEBUG(765, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy766;
+		if (yych != 't') goto yy187;
+yy766:
+		YYDEBUG(766, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'C') goto yy767;
+		if (yych != 'c') goto yy187;
+yy767:
+		YYDEBUG(767, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'H') goto yy768;
+		if (yych != 'h') goto yy187;
+yy768:
+		YYDEBUG(768, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(765, *YYCURSOR);
+		YYDEBUG(769, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1062 "Zend/zend_language_scanner.l"
+#line 1122 "Zend/zend_language_scanner.l"
+		{
+	return T_ENDSWITCH;
+}
+#line 7039 "Zend/zend_language_scanner.c"
+yy770:
+		YYDEBUG(770, *YYCURSOR);
+		++YYCURSOR;
+		if (yybm[0+(yych = *YYCURSOR)] & 4) {
+			goto yy186;
+		}
+		YYDEBUG(771, *YYCURSOR);
+		yyleng = YYCURSOR - SCNG(yy_text);
+#line 1066 "Zend/zend_language_scanner.l"
 		{
 	return T_ENDIF;
 }
-#line 7016 "Zend/zend_language_scanner.c"
-yy766:
-		YYDEBUG(766, *YYCURSOR);
+#line 7052 "Zend/zend_language_scanner.c"
+yy772:
+		YYDEBUG(772, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy767;
-		if (yych != 'r') goto yy186;
-yy767:
-		YYDEBUG(767, *YYCURSOR);
+		if (yych == 'R') goto yy773;
+		if (yych != 'r') goto yy187;
+yy773:
+		YYDEBUG(773, *YYCURSOR);
 		++YYCURSOR;
 		if ((yych = *YYCURSOR) <= '^') {
 			if (yych <= '@') {
-				if (yych <= '/') goto yy768;
-				if (yych <= '9') goto yy185;
+				if (yych <= '/') goto yy774;
+				if (yych <= '9') goto yy186;
 			} else {
-				if (yych == 'E') goto yy769;
-				if (yych <= 'Z') goto yy185;
+				if (yych == 'E') goto yy775;
+				if (yych <= 'Z') goto yy186;
 			}
 		} else {
 			if (yych <= 'd') {
-				if (yych != '`') goto yy185;
+				if (yych != '`') goto yy186;
 			} else {
-				if (yych <= 'e') goto yy769;
-				if (yych <= 'z') goto yy185;
-				if (yych >= 0x7F) goto yy185;
+				if (yych <= 'e') goto yy775;
+				if (yych <= 'z') goto yy186;
+				if (yych >= 0x7F) goto yy186;
 			}
 		}
-yy768:
-		YYDEBUG(768, *YYCURSOR);
+yy774:
+		YYDEBUG(774, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1086 "Zend/zend_language_scanner.l"
+#line 1090 "Zend/zend_language_scanner.l"
 		{
 	return T_ENDFOR;
 }
-#line 7049 "Zend/zend_language_scanner.c"
-yy769:
-		YYDEBUG(769, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy770;
-		if (yych != 'a') goto yy186;
-yy770:
-		YYDEBUG(770, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy771;
-		if (yych != 'c') goto yy186;
-yy771:
-		YYDEBUG(771, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'H') goto yy772;
-		if (yych != 'h') goto yy186;
-yy772:
-		YYDEBUG(772, *YYCURSOR);
-		++YYCURSOR;
-		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
-		}
-		YYDEBUG(773, *YYCURSOR);
-		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1094 "Zend/zend_language_scanner.l"
-		{
-	return T_ENDFOREACH;
-}
-#line 7077 "Zend/zend_language_scanner.c"
-yy774:
-		YYDEBUG(774, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'C') goto yy775;
-		if (yych != 'c') goto yy186;
+#line 7085 "Zend/zend_language_scanner.c"
 yy775:
 		YYDEBUG(775, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'L') goto yy776;
-		if (yych != 'l') goto yy186;
+		if (yych == 'A') goto yy776;
+		if (yych != 'a') goto yy187;
 yy776:
 		YYDEBUG(776, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'A') goto yy777;
-		if (yych != 'a') goto yy186;
+		if (yych == 'C') goto yy777;
+		if (yych != 'c') goto yy187;
 yy777:
 		YYDEBUG(777, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'R') goto yy778;
-		if (yych != 'r') goto yy186;
+		if (yych == 'H') goto yy778;
+		if (yych != 'h') goto yy187;
 yy778:
 		YYDEBUG(778, *YYCURSOR);
-		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy779;
-		if (yych != 'e') goto yy186;
-yy779:
-		YYDEBUG(779, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(780, *YYCURSOR);
+		YYDEBUG(779, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1102 "Zend/zend_language_scanner.l"
+#line 1098 "Zend/zend_language_scanner.l"
 		{
-	return T_ENDDECLARE;
+	return T_ENDFOREACH;
 }
-#line 7115 "Zend/zend_language_scanner.c"
+#line 7113 "Zend/zend_language_scanner.c"
+yy780:
+		YYDEBUG(780, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'C') goto yy781;
+		if (yych != 'c') goto yy187;
 yy781:
 		YYDEBUG(781, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'T') goto yy782;
-		if (yych != 't') goto yy186;
+		if (yych == 'L') goto yy782;
+		if (yych != 'l') goto yy187;
 yy782:
 		YYDEBUG(782, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'Y') goto yy783;
-		if (yych != 'y') goto yy186;
+		if (yych == 'A') goto yy783;
+		if (yych != 'a') goto yy187;
 yy783:
 		YYDEBUG(783, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'R') goto yy784;
+		if (yych != 'r') goto yy187;
+yy784:
+		YYDEBUG(784, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'E') goto yy785;
+		if (yych != 'e') goto yy187;
+yy785:
+		YYDEBUG(785, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(784, *YYCURSOR);
+		YYDEBUG(786, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1288 "Zend/zend_language_scanner.l"
+#line 1106 "Zend/zend_language_scanner.l"
+		{
+	return T_ENDDECLARE;
+}
+#line 7151 "Zend/zend_language_scanner.c"
+yy787:
+		YYDEBUG(787, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'T') goto yy788;
+		if (yych != 't') goto yy187;
+yy788:
+		YYDEBUG(788, *YYCURSOR);
+		yych = *++YYCURSOR;
+		if (yych == 'Y') goto yy789;
+		if (yych != 'y') goto yy187;
+yy789:
+		YYDEBUG(789, *YYCURSOR);
+		++YYCURSOR;
+		if (yybm[0+(yych = *YYCURSOR)] & 4) {
+			goto yy186;
+		}
+		YYDEBUG(790, *YYCURSOR);
+		yyleng = YYCURSOR - SCNG(yy_text);
+#line 1292 "Zend/zend_language_scanner.l"
 		{
 	return T_EMPTY;
 }
-#line 7138 "Zend/zend_language_scanner.c"
-yy785:
-		YYDEBUG(785, *YYCURSOR);
+#line 7174 "Zend/zend_language_scanner.c"
+yy791:
+		YYDEBUG(791, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'E') goto yy786;
-		if (yych != 'e') goto yy186;
-yy786:
-		YYDEBUG(786, *YYCURSOR);
+		if (yych == 'E') goto yy792;
+		if (yych != 'e') goto yy187;
+yy792:
+		YYDEBUG(792, *YYCURSOR);
 		++YYCURSOR;
 		if ((yych = *YYCURSOR) <= '^') {
 			if (yych <= '@') {
-				if (yych <= '/') goto yy787;
-				if (yych <= '9') goto yy185;
+				if (yych <= '/') goto yy793;
+				if (yych <= '9') goto yy186;
 			} else {
-				if (yych == 'I') goto yy788;
-				if (yych <= 'Z') goto yy185;
+				if (yych == 'I') goto yy794;
+				if (yych <= 'Z') goto yy186;
 			}
 		} else {
 			if (yych <= 'h') {
-				if (yych != '`') goto yy185;
+				if (yych != '`') goto yy186;
 			} else {
-				if (yych <= 'i') goto yy788;
-				if (yych <= 'z') goto yy185;
-				if (yych >= 0x7F) goto yy185;
+				if (yych <= 'i') goto yy794;
+				if (yych <= 'z') goto yy186;
+				if (yych >= 0x7F) goto yy186;
 			}
 		}
-yy787:
-		YYDEBUG(787, *YYCURSOR);
+yy793:
+		YYDEBUG(793, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1066 "Zend/zend_language_scanner.l"
+#line 1070 "Zend/zend_language_scanner.l"
 		{
 	return T_ELSE;
 }
-#line 7171 "Zend/zend_language_scanner.c"
-yy788:
-		YYDEBUG(788, *YYCURSOR);
+#line 7207 "Zend/zend_language_scanner.c"
+yy794:
+		YYDEBUG(794, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'F') goto yy789;
-		if (yych != 'f') goto yy186;
-yy789:
-		YYDEBUG(789, *YYCURSOR);
+		if (yych == 'F') goto yy795;
+		if (yych != 'f') goto yy187;
+yy795:
+		YYDEBUG(795, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(790, *YYCURSOR);
+		YYDEBUG(796, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1058 "Zend/zend_language_scanner.l"
+#line 1062 "Zend/zend_language_scanner.l"
 		{
 	return T_ELSEIF;
 }
-#line 7189 "Zend/zend_language_scanner.c"
-yy791:
-		YYDEBUG(791, *YYCURSOR);
+#line 7225 "Zend/zend_language_scanner.c"
+yy797:
+		YYDEBUG(797, *YYCURSOR);
 		yych = *++YYCURSOR;
-		if (yych == 'O') goto yy792;
-		if (yych != 'o') goto yy186;
-yy792:
-		YYDEBUG(792, *YYCURSOR);
+		if (yych == 'O') goto yy798;
+		if (yych != 'o') goto yy187;
+yy798:
+		YYDEBUG(798, *YYCURSOR);
 		++YYCURSOR;
 		if (yybm[0+(yych = *YYCURSOR)] & 4) {
-			goto yy185;
+			goto yy186;
 		}
-		YYDEBUG(793, *YYCURSOR);
+		YYDEBUG(799, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1142 "Zend/zend_language_scanner.l"
+#line 1146 "Zend/zend_language_scanner.l"
 		{
 	return T_ECHO;
 }
-#line 7207 "Zend/zend_language_scanner.c"
+#line 7243 "Zend/zend_language_scanner.c"
 	}
 /* *********************************** */
 yyc_ST_LOOKING_FOR_PROPERTY:
@@ -7242,41 +7278,41 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 			 64,  64,  64,  64,  64,  64,  64,  64, 
 			 64,  64,  64,  64,  64,  64,  64,  64, 
 		};
-		YYDEBUG(794, *YYCURSOR);
+		YYDEBUG(800, *YYCURSOR);
 		YYFILL(2);
 		yych = *YYCURSOR;
 		if (yych <= '-') {
 			if (yych <= '\r') {
-				if (yych <= 0x08) goto yy802;
-				if (yych <= '\n') goto yy796;
-				if (yych <= '\f') goto yy802;
+				if (yych <= 0x08) goto yy808;
+				if (yych <= '\n') goto yy802;
+				if (yych <= '\f') goto yy808;
 			} else {
-				if (yych == ' ') goto yy796;
-				if (yych <= ',') goto yy802;
-				goto yy798;
+				if (yych == ' ') goto yy802;
+				if (yych <= ',') goto yy808;
+				goto yy804;
 			}
 		} else {
 			if (yych <= '_') {
-				if (yych <= '@') goto yy802;
-				if (yych <= 'Z') goto yy800;
-				if (yych <= '^') goto yy802;
-				goto yy800;
+				if (yych <= '@') goto yy808;
+				if (yych <= 'Z') goto yy806;
+				if (yych <= '^') goto yy808;
+				goto yy806;
 			} else {
-				if (yych <= '`') goto yy802;
-				if (yych <= 'z') goto yy800;
-				if (yych <= '~') goto yy802;
-				goto yy800;
+				if (yych <= '`') goto yy808;
+				if (yych <= 'z') goto yy806;
+				if (yych <= '~') goto yy808;
+				goto yy806;
 			}
 		}
-yy796:
-		YYDEBUG(796, *YYCURSOR);
+yy802:
+		YYDEBUG(802, *YYCURSOR);
 		++YYCURSOR;
 		yych = *YYCURSOR;
-		goto yy808;
-yy797:
-		YYDEBUG(797, *YYCURSOR);
+		goto yy814;
+yy803:
+		YYDEBUG(803, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1175 "Zend/zend_language_scanner.l"
+#line 1179 "Zend/zend_language_scanner.l"
 		{
 	zendlval->value.str.val = yytext; /* no copying - intentional */
 	zendlval->value.str.len = yyleng;
@@ -7284,73 +7320,73 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	HANDLE_NEWLINES(yytext, yyleng);
 	return T_WHITESPACE;
 }
-#line 7288 "Zend/zend_language_scanner.c"
-yy798:
-		YYDEBUG(798, *YYCURSOR);
+#line 7324 "Zend/zend_language_scanner.c"
+yy804:
+		YYDEBUG(804, *YYCURSOR);
 		++YYCURSOR;
-		if ((yych = *YYCURSOR) == '>') goto yy805;
-yy799:
-		YYDEBUG(799, *YYCURSOR);
+		if ((yych = *YYCURSOR) == '>') goto yy811;
+yy805:
+		YYDEBUG(805, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1194 "Zend/zend_language_scanner.l"
+#line 1198 "Zend/zend_language_scanner.l"
 		{
 	yyless(0);
 	yy_pop_state(TSRMLS_C);
 	goto restart;
 }
-#line 7302 "Zend/zend_language_scanner.c"
-yy800:
-		YYDEBUG(800, *YYCURSOR);
+#line 7338 "Zend/zend_language_scanner.c"
+yy806:
+		YYDEBUG(806, *YYCURSOR);
 		++YYCURSOR;
 		yych = *YYCURSOR;
-		goto yy804;
-yy801:
-		YYDEBUG(801, *YYCURSOR);
+		goto yy810;
+yy807:
+		YYDEBUG(807, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1187 "Zend/zend_language_scanner.l"
+#line 1191 "Zend/zend_language_scanner.l"
 		{
 	yy_pop_state(TSRMLS_C);
 	zend_copy_value(zendlval, yytext, yyleng);
 	zendlval->type = IS_STRING;
 	return T_STRING;
 }
-#line 7318 "Zend/zend_language_scanner.c"
-yy802:
-		YYDEBUG(802, *YYCURSOR);
+#line 7354 "Zend/zend_language_scanner.c"
+yy808:
+		YYDEBUG(808, *YYCURSOR);
 		yych = *++YYCURSOR;
-		goto yy799;
-yy803:
-		YYDEBUG(803, *YYCURSOR);
+		goto yy805;
+yy809:
+		YYDEBUG(809, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-yy804:
-		YYDEBUG(804, *YYCURSOR);
+yy810:
+		YYDEBUG(810, *YYCURSOR);
 		if (yybm[0+yych] & 64) {
-			goto yy803;
+			goto yy809;
 		}
-		goto yy801;
-yy805:
-		YYDEBUG(805, *YYCURSOR);
+		goto yy807;
+yy811:
+		YYDEBUG(811, *YYCURSOR);
 		++YYCURSOR;
-		YYDEBUG(806, *YYCURSOR);
+		YYDEBUG(812, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1183 "Zend/zend_language_scanner.l"
+#line 1187 "Zend/zend_language_scanner.l"
 		{
 	return T_OBJECT_OPERATOR;
 }
-#line 7343 "Zend/zend_language_scanner.c"
-yy807:
-		YYDEBUG(807, *YYCURSOR);
+#line 7379 "Zend/zend_language_scanner.c"
+yy813:
+		YYDEBUG(813, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-yy808:
-		YYDEBUG(808, *YYCURSOR);
+yy814:
+		YYDEBUG(814, *YYCURSOR);
 		if (yybm[0+yych] & 128) {
-			goto yy807;
+			goto yy813;
 		}
-		goto yy797;
+		goto yy803;
 	}
 /* *********************************** */
 yyc_ST_LOOKING_FOR_VARNAME:
@@ -7389,74 +7425,74 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 			128, 128, 128, 128, 128, 128, 128, 128, 
 			128, 128, 128, 128, 128, 128, 128, 128, 
 		};
-		YYDEBUG(809, *YYCURSOR);
+		YYDEBUG(815, *YYCURSOR);
 		YYFILL(2);
 		yych = *YYCURSOR;
 		if (yych <= '_') {
-			if (yych <= '@') goto yy813;
-			if (yych <= 'Z') goto yy811;
-			if (yych <= '^') goto yy813;
+			if (yych <= '@') goto yy819;
+			if (yych <= 'Z') goto yy817;
+			if (yych <= '^') goto yy819;
 		} else {
-			if (yych <= '`') goto yy813;
-			if (yych <= 'z') goto yy811;
-			if (yych <= '~') goto yy813;
+			if (yych <= '`') goto yy819;
+			if (yych <= 'z') goto yy817;
+			if (yych <= '~') goto yy819;
 		}
-yy811:
-		YYDEBUG(811, *YYCURSOR);
+yy817:
+		YYDEBUG(817, *YYCURSOR);
 		yyaccept = 0;
 		yych = *(YYMARKER = ++YYCURSOR);
 		if (yych <= '_') {
 			if (yych <= '@') {
-				if (yych <= '/') goto yy812;
-				if (yych <= '9') goto yy815;
+				if (yych <= '/') goto yy818;
+				if (yych <= '9') goto yy821;
 			} else {
-				if (yych <= '[') goto yy815;
-				if (yych >= '_') goto yy815;
+				if (yych <= '[') goto yy821;
+				if (yych >= '_') goto yy821;
 			}
 		} else {
 			if (yych <= '|') {
-				if (yych <= '`') goto yy812;
-				if (yych <= 'z') goto yy815;
+				if (yych <= '`') goto yy818;
+				if (yych <= 'z') goto yy821;
 			} else {
-				if (yych != '~') goto yy815;
+				if (yych != '~') goto yy821;
 			}
 		}
-yy812:
-		YYDEBUG(812, *YYCURSOR);
+yy818:
+		YYDEBUG(818, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1480 "Zend/zend_language_scanner.l"
+#line 1484 "Zend/zend_language_scanner.l"
 		{
 	yyless(0);
 	yy_pop_state(TSRMLS_C);
 	yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
 	goto restart;
 }
-#line 7435 "Zend/zend_language_scanner.c"
-yy813:
-		YYDEBUG(813, *YYCURSOR);
+#line 7471 "Zend/zend_language_scanner.c"
+yy819:
+		YYDEBUG(819, *YYCURSOR);
 		yych = *++YYCURSOR;
-		goto yy812;
-yy814:
-		YYDEBUG(814, *YYCURSOR);
+		goto yy818;
+yy820:
+		YYDEBUG(820, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-yy815:
-		YYDEBUG(815, *YYCURSOR);
+yy821:
+		YYDEBUG(821, *YYCURSOR);
 		if (yybm[0+yych] & 128) {
-			goto yy814;
+			goto yy820;
 		}
-		if (yych == '[') goto yy817;
-		if (yych == '}') goto yy817;
-		YYDEBUG(816, *YYCURSOR);
+		if (yych == '[') goto yy823;
+		if (yych == '}') goto yy823;
+		YYDEBUG(822, *YYCURSOR);
 		YYCURSOR = YYMARKER;
-		goto yy812;
-yy817:
-		YYDEBUG(817, *YYCURSOR);
+		goto yy818;
+yy823:
+		YYDEBUG(823, *YYCURSOR);
 		++YYCURSOR;
-		YYDEBUG(818, *YYCURSOR);
+		YYDEBUG(824, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1470 "Zend/zend_language_scanner.l"
+#line 1474 "Zend/zend_language_scanner.l"
 		{
 	yyless(yyleng - 1);
 	zend_copy_value(zendlval, yytext, yyleng);
@@ -7465,18 +7501,18 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
 	return T_STRING_VARNAME;
 }
-#line 7469 "Zend/zend_language_scanner.c"
+#line 7505 "Zend/zend_language_scanner.c"
 	}
 /* *********************************** */
 yyc_ST_NOWDOC:
-	YYDEBUG(819, *YYCURSOR);
+	YYDEBUG(825, *YYCURSOR);
 	YYFILL(1);
 	yych = *YYCURSOR;
-	YYDEBUG(821, *YYCURSOR);
+	YYDEBUG(827, *YYCURSOR);
 	++YYCURSOR;
-	YYDEBUG(822, *YYCURSOR);
+	YYDEBUG(828, *YYCURSOR);
 	yyleng = YYCURSOR - SCNG(yy_text);
-#line 2364 "Zend/zend_language_scanner.l"
+#line 2368 "Zend/zend_language_scanner.l"
 	{
 	int newline = 0;
 
@@ -7533,7 +7569,7 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	HANDLE_NEWLINES(yytext, yyleng - newline);
 	return T_ENCAPSED_AND_WHITESPACE;
 }
-#line 7537 "Zend/zend_language_scanner.c"
+#line 7573 "Zend/zend_language_scanner.c"
 /* *********************************** */
 yyc_ST_VAR_OFFSET:
 	{
@@ -7571,76 +7607,76 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 			 16,  16,  16,  16,  16,  16,  16,  16, 
 			 16,  16,  16,  16,  16,  16,  16,  16, 
 		};
-		YYDEBUG(823, *YYCURSOR);
+		YYDEBUG(829, *YYCURSOR);
 		YYFILL(3);
 		yych = *YYCURSOR;
 		if (yych <= '/') {
 			if (yych <= ' ') {
 				if (yych <= '\f') {
-					if (yych <= 0x08) goto yy837;
-					if (yych <= '\n') goto yy833;
-					goto yy837;
+					if (yych <= 0x08) goto yy843;
+					if (yych <= '\n') goto yy839;
+					goto yy843;
 				} else {
-					if (yych <= '\r') goto yy833;
-					if (yych <= 0x1F) goto yy837;
-					goto yy833;
+					if (yych <= '\r') goto yy839;
+					if (yych <= 0x1F) goto yy843;
+					goto yy839;
 				}
 			} else {
 				if (yych <= '$') {
-					if (yych <= '"') goto yy832;
-					if (yych <= '#') goto yy833;
-					goto yy828;
+					if (yych <= '"') goto yy838;
+					if (yych <= '#') goto yy839;
+					goto yy834;
 				} else {
-					if (yych == '\'') goto yy833;
-					goto yy832;
+					if (yych == '\'') goto yy839;
+					goto yy838;
 				}
 			}
 		} else {
 			if (yych <= '\\') {
 				if (yych <= '@') {
-					if (yych <= '0') goto yy825;
-					if (yych <= '9') goto yy827;
-					goto yy832;
+					if (yych <= '0') goto yy831;
+					if (yych <= '9') goto yy833;
+					goto yy838;
 				} else {
-					if (yych <= 'Z') goto yy835;
-					if (yych <= '[') goto yy832;
-					goto yy833;
+					if (yych <= 'Z') goto yy841;
+					if (yych <= '[') goto yy838;
+					goto yy839;
 				}
 			} else {
 				if (yych <= '_') {
-					if (yych <= ']') goto yy830;
-					if (yych <= '^') goto yy832;
-					goto yy835;
+					if (yych <= ']') goto yy836;
+					if (yych <= '^') goto yy838;
+					goto yy841;
 				} else {
-					if (yych <= '`') goto yy832;
-					if (yych <= 'z') goto yy835;
-					if (yych <= '~') goto yy832;
-					goto yy835;
+					if (yych <= '`') goto yy838;
+					if (yych <= 'z') goto yy841;
+					if (yych <= '~') goto yy838;
+					goto yy841;
 				}
 			}
 		}
-yy825:
-		YYDEBUG(825, *YYCURSOR);
+yy831:
+		YYDEBUG(831, *YYCURSOR);
 		yyaccept = 0;
 		yych = *(YYMARKER = ++YYCURSOR);
 		if (yych <= 'W') {
 			if (yych <= '9') {
-				if (yych >= '0') goto yy849;
+				if (yych >= '0') goto yy855;
 			} else {
-				if (yych == 'B') goto yy846;
+				if (yych == 'B') goto yy852;
 			}
 		} else {
 			if (yych <= 'b') {
-				if (yych <= 'X') goto yy848;
-				if (yych >= 'b') goto yy846;
+				if (yych <= 'X') goto yy854;
+				if (yych >= 'b') goto yy852;
 			} else {
-				if (yych == 'x') goto yy848;
+				if (yych == 'x') goto yy854;
 			}
 		}
-yy826:
-		YYDEBUG(826, *YYCURSOR);
+yy832:
+		YYDEBUG(832, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1558 "Zend/zend_language_scanner.l"
+#line 1562 "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)) {
 		zendlval->value.lval = strtol(yytext, NULL, 10);
@@ -7652,81 +7688,81 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	}
 	return T_NUM_STRING;
 }
-#line 7656 "Zend/zend_language_scanner.c"
-yy827:
-		YYDEBUG(827, *YYCURSOR);
+#line 7692 "Zend/zend_language_scanner.c"
+yy833:
+		YYDEBUG(833, *YYCURSOR);
 		yych = *++YYCURSOR;
-		goto yy845;
-yy828:
-		YYDEBUG(828, *YYCURSOR);
+		goto yy851;
+yy834:
+		YYDEBUG(834, *YYCURSOR);
 		++YYCURSOR;
 		if ((yych = *YYCURSOR) <= '_') {
-			if (yych <= '@') goto yy829;
-			if (yych <= 'Z') goto yy841;
-			if (yych >= '_') goto yy841;
+			if (yych <= '@') goto yy835;
+			if (yych <= 'Z') goto yy847;
+			if (yych >= '_') goto yy847;
 		} else {
-			if (yych <= '`') goto yy829;
-			if (yych <= 'z') goto yy841;
-			if (yych >= 0x7F) goto yy841;
+			if (yych <= '`') goto yy835;
+			if (yych <= 'z') goto yy847;
+			if (yych >= 0x7F) goto yy847;
 		}
-yy829:
-		YYDEBUG(829, *YYCURSOR);
+yy835:
+		YYDEBUG(835, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1890 "Zend/zend_language_scanner.l"
+#line 1894 "Zend/zend_language_scanner.l"
 		{
 	/* Only '[' can be valid, but returning other tokens will allow a more explicit parse error */
 	return yytext[0];
 }
-#line 7681 "Zend/zend_language_scanner.c"
-yy830:
-		YYDEBUG(830, *YYCURSOR);
+#line 7717 "Zend/zend_language_scanner.c"
+yy836:
+		YYDEBUG(836, *YYCURSOR);
 		++YYCURSOR;
-		YYDEBUG(831, *YYCURSOR);
+		YYDEBUG(837, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1885 "Zend/zend_language_scanner.l"
+#line 1889 "Zend/zend_language_scanner.l"
 		{
 	yy_pop_state(TSRMLS_C);
 	return ']';
 }
-#line 7692 "Zend/zend_language_scanner.c"
-yy832:
-		YYDEBUG(832, *YYCURSOR);
+#line 7728 "Zend/zend_language_scanner.c"
+yy838:
+		YYDEBUG(838, *YYCURSOR);
 		yych = *++YYCURSOR;
-		goto yy829;
-yy833:
-		YYDEBUG(833, *YYCURSOR);
+		goto yy835;
+yy839:
+		YYDEBUG(839, *YYCURSOR);
 		++YYCURSOR;
-		YYDEBUG(834, *YYCURSOR);
+		YYDEBUG(840, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1895 "Zend/zend_language_scanner.l"
+#line 1899 "Zend/zend_language_scanner.l"
 		{
 	/* Invalid rule to return a more explicit parse error with proper line number */
 	yyless(0);
 	yy_pop_state(TSRMLS_C);
 	return T_ENCAPSED_AND_WHITESPACE;
 }
-#line 7709 "Zend/zend_language_scanner.c"
-yy835:
-		YYDEBUG(835, *YYCURSOR);
+#line 7745 "Zend/zend_language_scanner.c"
+yy841:
+		YYDEBUG(841, *YYCURSOR);
 		++YYCURSOR;
 		yych = *YYCURSOR;
-		goto yy840;
-yy836:
-		YYDEBUG(836, *YYCURSOR);
+		goto yy846;
+yy842:
+		YYDEBUG(842, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1902 "Zend/zend_language_scanner.l"
+#line 1906 "Zend/zend_language_scanner.l"
 		{
 	zend_copy_value(zendlval, yytext, yyleng);
 	zendlval->type = IS_STRING;
 	return T_STRING;
 }
-#line 7724 "Zend/zend_language_scanner.c"
-yy837:
-		YYDEBUG(837, *YYCURSOR);
+#line 7760 "Zend/zend_language_scanner.c"
+yy843:
+		YYDEBUG(843, *YYCURSOR);
 		++YYCURSOR;
-		YYDEBUG(838, *YYCURSOR);
+		YYDEBUG(844, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 2422 "Zend/zend_language_scanner.l"
+#line 2426 "Zend/zend_language_scanner.l"
 		{
 	if (YYCURSOR > YYLIMIT) {
 		return 0;
@@ -7735,118 +7771,118 @@ int lex_scan(zval *zendlval TSRMLS_DC)
 	zend_error(E_COMPILE_WARNING,"Unexpected character in input:  '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
 	goto restart;
 }
-#line 7739 "Zend/zend_language_scanner.c"
-yy839:
-		YYDEBUG(839, *YYCURSOR);
+#line 7775 "Zend/zend_language_scanner.c"
+yy845:
+		YYDEBUG(845, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-yy840:
-		YYDEBUG(840, *YYCURSOR);
+yy846:
+		YYDEBUG(846, *YYCURSOR);
 		if (yybm[0+yych] & 16) {
-			goto yy839;
+			goto yy845;
 		}
-		goto yy836;
-yy841:
-		YYDEBUG(841, *YYCURSOR);
+		goto yy842;
+yy847:
+		YYDEBUG(847, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(842, *YYCURSOR);
+		YYDEBUG(848, *YYCURSOR);
 		if (yych <= '^') {
 			if (yych <= '9') {
-				if (yych >= '0') goto yy841;
+				if (yych >= '0') goto yy847;
 			} else {
-				if (yych <= '@') goto yy843;
-				if (yych <= 'Z') goto yy841;
+				if (yych <= '@') goto yy849;
+				if (yych <= 'Z') goto yy847;
 			}
 		} else {
 			if (yych <= '`') {
-				if (yych <= '_') goto yy841;
+				if (yych <= '_') goto yy847;
 			} else {
-				if (yych <= 'z') goto yy841;
-				if (yych >= 0x7F) goto yy841;
+				if (yych <= 'z') goto yy847;
+				if (yych >= 0x7F) goto yy847;
 			}
 		}
-yy843:
-		YYDEBUG(843, *YYCURSOR);
+yy849:
+		YYDEBUG(849, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1879 "Zend/zend_language_scanner.l"
+#line 1883 "Zend/zend_language_scanner.l"
 		{
 	zend_copy_value(zendlval, (yytext+1), (yyleng-1));
 	zendlval->type = IS_STRING;
 	return T_VARIABLE;
 }
-#line 7781 "Zend/zend_language_scanner.c"
-yy844:
-		YYDEBUG(844, *YYCURSOR);
+#line 7817 "Zend/zend_language_scanner.c"
+yy850:
+		YYDEBUG(850, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-yy845:
-		YYDEBUG(845, *YYCURSOR);
+yy851:
+		YYDEBUG(851, *YYCURSOR);
 		if (yybm[0+yych] & 32) {
-			goto yy844;
+			goto yy850;
 		}
-		goto yy826;
-yy846:
-		YYDEBUG(846, *YYCURSOR);
+		goto yy832;
+yy852:
+		YYDEBUG(852, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yybm[0+yych] & 128) {
-			goto yy854;
+			goto yy860;
 		}
-yy847:
-		YYDEBUG(847, *YYCURSOR);
+yy853:
+		YYDEBUG(853, *YYCURSOR);
 		YYCURSOR = YYMARKER;
-		goto yy826;
-yy848:
-		YYDEBUG(848, *YYCURSOR);
+		goto yy832;
+yy854:
+		YYDEBUG(854, *YYCURSOR);
 		yych = *++YYCURSOR;
 		if (yybm[0+yych] & 64) {
-			goto yy852;
+			goto yy858;
 		}
-		goto yy847;
-yy849:
-		YYDEBUG(849, *YYCURSOR);
+		goto yy853;
+yy855:
+		YYDEBUG(855, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(850, *YYCURSOR);
-		if (yych <= '/') goto yy851;
-		if (yych <= '9') goto yy849;
-yy851:
-		YYDEBUG(851, *YYCURSOR);
+		YYDEBUG(856, *YYCURSOR);
+		if (yych <= '/') goto yy857;
+		if (yych <= '9') goto yy855;
+yy857:
+		YYDEBUG(857, *YYCURSOR);
 		yyleng = YYCURSOR - SCNG(yy_text);
-#line 1570 "Zend/zend_language_scanner.l"
+#line 1574 "Zend/zend_language_scanner.l"
 		{ /* Offset must be treated as a string */
 	zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
 	zendlval->value.str.len = yyleng;
 	zendlval->type = IS_STRING;
 	return T_NUM_STRING;
 }
-#line 7828 "Zend/zend_language_scanner.c"
-yy852:
-		YYDEBUG(852, *YYCURSOR);
+#line 7864 "Zend/zend_language_scanner.c"
+yy858:
+		YYDEBUG(858, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(853, *YYCURSOR);
+		YYDEBUG(859, *YYCURSOR);
 		if (yybm[0+yych] & 64) {
-			goto yy852;
+			goto yy858;
 		}
-		goto yy851;
-yy854:
-		YYDEBUG(854, *YYCURSOR);
+		goto yy857;
+yy860:
+		YYDEBUG(860, *YYCURSOR);
 		++YYCURSOR;
 		YYFILL(1);
 		yych = *YYCURSOR;
-		YYDEBUG(855, *YYCURSOR);
+		YYDEBUG(861, *YYCURSOR);
 		if (yybm[0+yych] & 128) {
-			goto yy854;
+			goto yy860;
 		}
-		goto yy851;
+		goto yy857;
 	}
 }
-#line 2431 "Zend/zend_language_scanner.l"
+#line 2435 "Zend/zend_language_scanner.l"
 
 }
diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l
index e8a5e5a6dc3ad..dbf43977fb86c 100644
--- a/Zend/zend_language_scanner.l
+++ b/Zend/zend_language_scanner.l
@@ -1035,6 +1035,10 @@ NEWLINE ("\r"|"\n"|"\r\n")
 	return T_RETURN;
 }
 
+<ST_IN_SCRIPTING>"yield" {
+	return T_YIELD;
+}
+
 <ST_IN_SCRIPTING>"try" {
 	return T_TRY;
 }
diff --git a/Zend/zend_language_scanner_defs.h b/Zend/zend_language_scanner_defs.h
index 5309ac2327886..47df7e92de316 100644
--- a/Zend/zend_language_scanner_defs.h
+++ b/Zend/zend_language_scanner_defs.h
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Sun Aug 19 20:57:55 2012 */
+/* Generated by re2c 0.13.5 on Mon Aug 20 13:34:50 2012 */
 #line 3 "Zend/zend_language_scanner_defs.h"
 
 enum YYCONDTYPE {
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 6c15829100431..5c4b20fd34820 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -579,6 +579,17 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
 			case ZEND_JMP_SET_VAR:
 				opline->op2.jmp_addr = &op_array->opcodes[opline->op2.opline_num];
 				break;
+			case ZEND_RETURN:
+			case ZEND_RETURN_BY_REF:
+				if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
+					if (opline->op1_type != IS_CONST || Z_TYPE_P(opline->op1.zv) != IS_NULL) {
+						CG(zend_lineno) = opline->lineno;
+						zend_error(E_COMPILE_ERROR, "Generators cannot return values using \"return\"");
+					}
+
+					opline->opcode = ZEND_GENERATOR_RETURN;
+				}
+				break;
 		}
 		ZEND_VM_SET_OPCODE_HANDLER(opline);
 		opline++;
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 92c5fcf40fe7f..ffd81b0378502 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -1845,17 +1845,22 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
 	zend_bool nested;
 	zend_op_array *op_array = EX(op_array);
 
+	/* Generators go throw a different cleanup process */
+	if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
+		/* The generator object is stored in return_value_ptr_ptr */
+		zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+		/* Close the generator to free up resources */
+		zend_generator_close(generator, 1 TSRMLS_CC);
+
+		/* Pass execution back to handling code */
+		ZEND_VM_RETURN();
+	}
+
 	EG(current_execute_data) = EX(prev_execute_data);
 	EG(opline_ptr) = NULL;
 	if (!EG(active_symbol_table)) {
-		zval ***cv = EX_CVs();
-		zval ***end = cv + op_array->last_var;
-		while (cv != end) {
-			if (*cv) {
-				zval_ptr_dtor(*cv);
-			}
-			cv++;
-		}
+		zend_free_compiled_variables(EX_CVs(), op_array->last_var);
 	}
 
 	if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->prototype) {
@@ -1864,7 +1869,13 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
 
 	nested = EX(nested);
 
-	zend_vm_stack_free(execute_data TSRMLS_CC);
+	/* For generators the execute_data is stored on the heap, for everything
+	 * else it is stored on the VM stack. */
+	if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
+		efree(execute_data);
+	} else {
+		zend_vm_stack_free(execute_data TSRMLS_CC);
+	}
 
 	if (nested) {
 		execute_data = EG(current_execute_data);
@@ -1902,20 +1913,11 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
 			ZEND_VM_INC_OPCODE();
 			ZEND_VM_LEAVE();
 		} else {
-
 			EG(opline_ptr) = &EX(opline);
 			EG(active_op_array) = EX(op_array);
 			EG(return_value_ptr_ptr) = EX(original_return_value);
 			if (EG(active_symbol_table)) {
-				if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
-					zend_hash_destroy(EG(active_symbol_table));
-					FREE_HASHTABLE(EG(active_symbol_table));
-				} else {
-					/* clean before putting into the cache, since clean
-					   could call dtors, which could use cached hash */
-					zend_hash_clean(EG(active_symbol_table));
-					*(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
-				}
+				zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
 			}
 			EG(active_symbol_table) = EX(symbol_table);
 
@@ -2048,7 +2050,11 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
 			ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
 		}
 
-		if (EXPECTED(zend_execute == execute)) {
+		if (EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) {
+			if (RETURN_VALUE_USED(opline)) {
+				EX_T(opline->result.var).var.ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
+			}
+		} else if (EXPECTED(zend_execute == execute)) {
 			if (EXPECTED(EG(exception) == NULL)) {
 				ZEND_VM_ENTER();
 			}
@@ -2060,22 +2066,14 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
 		EG(active_op_array) = EX(op_array);
 		EG(return_value_ptr_ptr) = EX(original_return_value);
 		if (EG(active_symbol_table)) {
-			if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
-				zend_hash_destroy(EG(active_symbol_table));
-				FREE_HASHTABLE(EG(active_symbol_table));
-			} else {
-				/* clean before putting into the cache, since clean
-				   could call dtors, which could use cached hash */
-				zend_hash_clean(EG(active_symbol_table));
-				*(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
-			}
+			zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
 		}
 		EG(active_symbol_table) = EX(symbol_table);
 	} else { /* ZEND_OVERLOADED_FUNCTION */
 		MAKE_STD_ZVAL(EX_T(opline->result.var).var.ptr);
 		ZVAL_NULL(EX_T(opline->result.var).var.ptr);
 
-			/* Not sure what should be done here if it's a static method */
+		/* Not sure what should be done here if it's a static method */
 		if (EXPECTED(EX(object) != NULL)) {
 			Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, opline->extended_value, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
 		} else {
@@ -3059,6 +3057,14 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
 	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type, ZEND_RETURN_BY_REF);
 }
 
+ZEND_VM_HANDLER(161, ZEND_GENERATOR_RETURN, ANY, ANY)
+{
+	if (EX(op_array)->has_finally_block) {
+		ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type, ZEND_RETURN);
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+}
+
 ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
 {
 	USE_OPLINE
@@ -5131,11 +5137,26 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
 	int i;
 	zend_uint catch_op_num = 0, finally_op_num = 0;
 	int catched = 0, finally = 0;
-	zval restored_error_reporting;
+	void **stack_frame;
 
-	void **stack_frame = (void**)(((char*)EX_Ts()) +
-		(ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T));
+	/* Figure out where the next stack frame (which maybe contains pushed
+	 * arguments that have to be dtor'ed) starts */
+	if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
+		/* The generator object is stored in return_value_ptr_ptr */
+		zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+		/* For generators the next stack frame is conveniently stored in the
+		 * generator object. */
+		stack_frame = generator->original_stack_top;
+	} else {
+		/* In all other cases the next stack frame starts after the temporary
+		 * variables section of the current execution context */
+		stack_frame = (void **) ((char *) EX_Ts() +
+			ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T);
+	}
 
+	/* If the exception was thrown during a function call there might be
+	 * arguments pushed to the stack that have to be dtor'ed. */
 	while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
 		zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
 		zval_ptr_dtor(&stack_zval_p);
@@ -5202,6 +5223,8 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
 
 	/* restore previous error_reporting value */
 	if (!EG(error_reporting) && EX(old_error_reporting) != NULL && Z_LVAL_P(EX(old_error_reporting)) != 0) {
+		zval restored_error_reporting;
+
 		Z_TYPE(restored_error_reporting) = IS_LONG;
 		Z_LVAL(restored_error_reporting) = Z_LVAL_P(EX(old_error_reporting));
 		convert_to_string(&restored_error_reporting);
@@ -5374,4 +5397,161 @@ ZEND_VM_HANDLER(159, ZEND_LEAVE, ANY, ANY)
 	ZEND_VM_CONTINUE();
 }
 
+ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSED)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (OP1_TYPE != IS_UNUSED) {
+		zend_free_op free_op1;
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = GET_OP1_ZVAL_PTR(BP_VAR_R);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!IS_OP1_TMP_FREE()) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+
+				if (OP1_TYPE == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (OP1_TYPE == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+				FREE_OP1_IF_VAR();
+			}
+		} else {
+			zval *value = GET_OP1_ZVAL_PTR(BP_VAR_R);
+
+			/* Consts, temporary variables and references need copying */
+			if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!IS_OP1_TMP_FREE()) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+			FREE_OP1_IF_VAR();
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (OP2_TYPE != IS_UNUSED) {
+		zend_free_op free_op2;
+		zval *key = GET_OP2_ZVAL_PTR(BP_VAR_R);
+
+		/* Consts, temporary variables and references need copying */
+		if (OP2_TYPE == IS_CONST || OP2_TYPE == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!IS_OP1_TMP_FREE()) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+		FREE_OP2_IF_VAR();
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 1e0b2b50a98d4..b0e05b1296aa9 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -339,30 +339,43 @@ static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* o
 #define EX_Ts() EX(Ts)
 
 
-ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
-{
-	DCL_OPLINE
+zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC) {
 	zend_execute_data *execute_data;
-	zend_bool nested = 0;
-	zend_bool original_in_execution = EG(in_execution);
 
-
-	if (EG(exception)) {
-		return;
+	/*
+	 * When allocating the execute_data, memory for compiled variables and
+	 * temporary variables is also allocated after the actual zend_execute_data
+	 * struct. op_array->last_var specifies the number of compiled variables and
+	 * op_array->T is the number of temporary variables. If there is no symbol
+	 * table, then twice as much memory is allocated for compiled variables.
+	 * In that case the first half contains zval**s and the second half the
+	 * actual zval*s (which would otherwise be in the symbol table).
+	 */
+	size_t execute_data_size = ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data));
+	size_t CVs_size = ZEND_MM_ALIGNED_SIZE(sizeof(zval **) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2));
+	size_t Ts_size = ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T;
+	size_t total_size = execute_data_size + CVs_size + Ts_size;
+
+	/*
+	 * Normally the execute_data is allocated on the VM stack (because it does
+	 * not actually do any allocation and thus is faster). For generators
+	 * though this behavior would be suboptimal, because the (rather large)
+	 * structure would have to be copied back and forth every time execution is
+	 * suspended or resumed. That's why for generators the execution context
+	 * is allocated using emalloc, thus allowing to save and restore it simply
+	 * by replacing a pointer.
+	 */
+	if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
+		execute_data = emalloc(total_size);
+	} else {
+		execute_data = zend_vm_stack_alloc(total_size TSRMLS_CC);
 	}
 
-	EG(in_execution) = 1;
+	EX(CVs) = (zval ***) ((char *) execute_data + execute_data_size);
+	memset(EX(CVs), 0, sizeof(zval **) * op_array->last_var);
 
-zend_vm_enter:
-	/* Initialize execute_data */
-	execute_data = (zend_execute_data *)zend_vm_stack_alloc(
-		ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) +
-		ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)) +
-		ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T TSRMLS_CC);
+	EX(Ts) = (temp_variable *) ((char *) EX(CVs) + CVs_size);
 
-	EX(CVs) = (zval***)((char*)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)));
-	memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
-	EX(Ts) = (temp_variable *)(((char*)EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)));
 	EX(fbc) = NULL;
 	EX(called_scope) = NULL;
 	EX(object) = NULL;
@@ -373,9 +386,6 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
 	EG(current_execute_data) = execute_data;
 	EX(nested) = nested;
     EX(leaving) = 0;
-	nested = 1;
-
-	LOAD_REGS();
 
 	if (!op_array->run_time_cache && op_array->last_cache_slot) {
 		op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
@@ -384,10 +394,10 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
 	if (op_array->this_var != -1 && EG(This)) {
  		Z_ADDREF_P(EG(This)); /* For $this pointer */
 		if (!EG(active_symbol_table)) {
-			EX_CV(op_array->this_var) = (zval**)EX_CVs() + (op_array->last_var + op_array->this_var);
-			*EX_CV(op_array->this_var) = EG(This);
+			EX(CVs)[op_array->this_var] = (zval **) EX(CVs) + op_array->last_var + op_array->this_var;
+			*EX(CVs)[op_array->this_var] = EG(This);
 		} else {
-			if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void**)&EX_CV(op_array->this_var))==FAILURE) {
+			if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void **) &EX(CVs)[op_array->this_var])==FAILURE) {
 				Z_DELREF_P(EG(This));
 			}
 		}
@@ -395,11 +405,30 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
 
 	EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
 	EG(opline_ptr) = &EX(opline);
-	LOAD_OPLINE();
 
 	EX(function_state).function = (zend_function *) op_array;
 	EX(function_state).arguments = NULL;
 
+	return execute_data;
+}
+
+ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC)
+{
+	DCL_OPLINE
+	zend_bool original_in_execution;
+
+
+
+	if (EG(exception)) {
+		return;
+	}
+
+	original_in_execution = EG(in_execution);
+	EG(in_execution) = 1;
+
+	LOAD_REGS();
+	LOAD_OPLINE();
+
 	while (1) {
     	int ret;
 #ifdef ZEND_WIN32
@@ -414,10 +443,11 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
 					EG(in_execution) = original_in_execution;
 					return;
 				case 2:
-					op_array = EG(active_op_array);
-					goto zend_vm_enter;
+					execute_data = zend_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC);
+					break;
 				case 3:
 					execute_data = EG(current_execute_data);
+					break;
 				default:
 					break;
 			}
@@ -427,22 +457,34 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
 	zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
 }
 
+ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
+{
+	zend_execute_data *execute_data = zend_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC);
+
+	execute_ex(execute_data TSRMLS_CC);
+}
+
 static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_bool nested;
 	zend_op_array *op_array = EX(op_array);
 
+	/* Generators go throw a different cleanup process */
+	if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
+		/* The generator object is stored in return_value_ptr_ptr */
+		zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+		/* Close the generator to free up resources */
+		zend_generator_close(generator, 1 TSRMLS_CC);
+
+		/* Pass execution back to handling code */
+		ZEND_VM_RETURN();
+	}
+
 	EG(current_execute_data) = EX(prev_execute_data);
 	EG(opline_ptr) = NULL;
 	if (!EG(active_symbol_table)) {
-		zval ***cv = EX_CVs();
-		zval ***end = cv + op_array->last_var;
-		while (cv != end) {
-			if (*cv) {
-				zval_ptr_dtor(*cv);
-			}
-			cv++;
-		}
+		zend_free_compiled_variables(EX_CVs(), op_array->last_var);
 	}
 
 	if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->prototype) {
@@ -451,7 +493,13 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 
 	nested = EX(nested);
 
-	zend_vm_stack_free(execute_data TSRMLS_CC);
+	/* For generators the execute_data is stored on the heap, for everything
+	 * else it is stored on the VM stack. */
+	if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
+		efree(execute_data);
+	} else {
+		zend_vm_stack_free(execute_data TSRMLS_CC);
+	}
 
 	if (nested) {
 		execute_data = EG(current_execute_data);
@@ -489,20 +537,11 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 			ZEND_VM_INC_OPCODE();
 			ZEND_VM_LEAVE();
 		} else {
-
 			EG(opline_ptr) = &EX(opline);
 			EG(active_op_array) = EX(op_array);
 			EG(return_value_ptr_ptr) = EX(original_return_value);
 			if (EG(active_symbol_table)) {
-				if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
-					zend_hash_destroy(EG(active_symbol_table));
-					FREE_HASHTABLE(EG(active_symbol_table));
-				} else {
-					/* clean before putting into the cache, since clean
-					   could call dtors, which could use cached hash */
-					zend_hash_clean(EG(active_symbol_table));
-					*(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
-				}
+				zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
 			}
 			EG(active_symbol_table) = EX(symbol_table);
 
@@ -635,7 +674,11 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
 			ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
 		}
 
-		if (EXPECTED(zend_execute == execute)) {
+		if (EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) {
+			if (RETURN_VALUE_USED(opline)) {
+				EX_T(opline->result.var).var.ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
+			}
+		} else if (EXPECTED(zend_execute == execute)) {
 			if (EXPECTED(EG(exception) == NULL)) {
 				ZEND_VM_ENTER();
 			}
@@ -647,22 +690,14 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
 		EG(active_op_array) = EX(op_array);
 		EG(return_value_ptr_ptr) = EX(original_return_value);
 		if (EG(active_symbol_table)) {
-			if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
-				zend_hash_destroy(EG(active_symbol_table));
-				FREE_HASHTABLE(EG(active_symbol_table));
-			} else {
-				/* clean before putting into the cache, since clean
-				   could call dtors, which could use cached hash */
-				zend_hash_clean(EG(active_symbol_table));
-				*(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
-			}
+			zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
 		}
 		EG(active_symbol_table) = EX(symbol_table);
 	} else { /* ZEND_OVERLOADED_FUNCTION */
 		MAKE_STD_ZVAL(EX_T(opline->result.var).var.ptr);
 		ZVAL_NULL(EX_T(opline->result.var).var.ptr);
 
-			/* Not sure what should be done here if it's a static method */
+		/* Not sure what should be done here if it's a static method */
 		if (EXPECTED(EX(object) != NULL)) {
 			Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, opline->extended_value, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
 		} else {
@@ -852,6 +887,14 @@ static int ZEND_FASTCALL  ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER
 	return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	if (EX(op_array)->has_finally_block) {
+		return zend_finally_handler_leaving_SPEC(ZEND_RETURN, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+	}
+	return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+}
+
 static int ZEND_FASTCALL  ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -1135,11 +1178,26 @@ static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
 	int i;
 	zend_uint catch_op_num = 0, finally_op_num = 0;
 	int catched = 0, finally = 0;
-	zval restored_error_reporting;
+	void **stack_frame;
 
-	void **stack_frame = (void**)(((char*)EX_Ts()) +
-		(ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T));
+	/* Figure out where the next stack frame (which maybe contains pushed
+	 * arguments that have to be dtor'ed) starts */
+	if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
+		/* The generator object is stored in return_value_ptr_ptr */
+		zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+		/* For generators the next stack frame is conveniently stored in the
+		 * generator object. */
+		stack_frame = generator->original_stack_top;
+	} else {
+		/* In all other cases the next stack frame starts after the temporary
+		 * variables section of the current execution context */
+		stack_frame = (void **) ((char *) EX_Ts() +
+			ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T);
+	}
 
+	/* If the exception was thrown during a function call there might be
+	 * arguments pushed to the stack that have to be dtor'ed. */
 	while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
 		zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
 		zval_ptr_dtor(&stack_zval_p);
@@ -1206,6 +1264,8 @@ static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
 
 	/* restore previous error_reporting value */
 	if (!EG(error_reporting) && EX(old_error_reporting) != NULL && Z_LVAL_P(EX(old_error_reporting)) != 0) {
+		zval restored_error_reporting;
+
 		Z_TYPE(restored_error_reporting) = IS_LONG;
 		Z_LVAL(restored_error_reporting) = Z_LVAL_P(EX(old_error_reporting));
 		convert_to_string(&restored_error_reporting);
@@ -4139,6 +4199,160 @@ static int ZEND_FASTCALL  ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCOD
 	ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_CONST != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = opline->op1.zv;
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_CONST == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = opline->op1.zv;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CONST != IS_UNUSED) {
+
+		zval *key = opline->op2.zv;
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -4679,6 +4893,160 @@ static int ZEND_FASTCALL  ZEND_INIT_ARRAY_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HAN
 	}
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_CONST != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = opline->op1.zv;
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_CONST == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = opline->op1.zv;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zend_free_op free_op2;
+		zval *key = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -5544,6 +5912,161 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPC
 	ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_CONST != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = opline->op1.zv;
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_CONST == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = opline->op1.zv;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_VAR != IS_UNUSED) {
+		zend_free_op free_op2;
+		zval *key = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -6103,6 +6626,160 @@ static int ZEND_FASTCALL  ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER
 	ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_CONST != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = opline->op1.zv;
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_CONST == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = opline->op1.zv;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_UNUSED != IS_UNUSED) {
+
+		zval *key = NULL;
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -6702,6 +7379,160 @@ static int ZEND_FASTCALL  ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAND
 	}
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_CONST != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = opline->op1.zv;
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_CONST == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = opline->op1.zv;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CV != IS_UNUSED) {
+
+		zval *key = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_BW_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -8610,6 +9441,160 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC
 	ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zend_free_op free_op1;
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!1) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_TMP_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!1) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CONST != IS_UNUSED) {
+
+		zval *key = opline->op2.zv;
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!1) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -9150,6 +10135,160 @@ static int ZEND_FASTCALL  ZEND_INIT_ARRAY_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDL
 	}
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zend_free_op free_op1;
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!1) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_TMP_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!1) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zend_free_op free_op2;
+		zval *key = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!1) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -10015,6 +11154,161 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
 	ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zend_free_op free_op1;
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!1) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_TMP_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!1) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_VAR != IS_UNUSED) {
+		zend_free_op free_op2;
+		zval *key = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!1) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -10440,6 +11734,160 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
 	ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zend_free_op free_op1;
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!1) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_TMP_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!1) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_UNUSED != IS_UNUSED) {
+
+		zval *key = NULL;
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!1) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -10977,6 +12425,160 @@ static int ZEND_FASTCALL  ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLE
 	}
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zend_free_op free_op1;
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!1) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_TMP_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!1) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CV != IS_UNUSED) {
+
+		zval *key = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!1) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_BW_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -14744,6 +16346,162 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CONST_HANDLER(ZEN
 	return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_VAR != IS_UNUSED) {
+		zend_free_op free_op1;
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+				if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+				if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+			}
+		} else {
+			zval *value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+			if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CONST != IS_UNUSED) {
+
+		zval *key = opline->op2.zv;
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -16671,6 +18429,162 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_
 	return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_VAR != IS_UNUSED) {
+		zend_free_op free_op1;
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+				if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+				if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+			}
+		} else {
+			zval *value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+			if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zend_free_op free_op2;
+		zval *key = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -18978,6 +20892,163 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_
 	return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_VAR != IS_UNUSED) {
+		zend_free_op free_op1;
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+				if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+				if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+			}
+		} else {
+			zval *value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+			if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_VAR != IS_UNUSED) {
+		zend_free_op free_op2;
+		zval *key = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -19962,6 +22033,162 @@ static int ZEND_FASTCALL  ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAND
 	ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_VAR != IS_UNUSED) {
+		zend_free_op free_op1;
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+				if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+				if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+			}
+		} else {
+			zval *value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+			if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_UNUSED != IS_UNUSED) {
+
+		zval *key = NULL;
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -21938,6 +24165,162 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CV_HANDLER(ZEND_O
 	return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_VAR != IS_UNUSED) {
+		zend_free_op free_op1;
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+				if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+				if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+			}
+		} else {
+			zval *value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+			if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CV != IS_UNUSED) {
+
+		zval *key = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -23273,6 +25656,160 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER(
 	return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CONST(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_UNUSED != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = NULL;
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_UNUSED == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = NULL;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CONST != IS_UNUSED) {
+
+		zval *key = opline->op2.zv;
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -24432,6 +26969,160 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER(ZE
 	return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_UNUSED != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = NULL;
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_UNUSED == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = NULL;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zend_free_op free_op2;
+		zval *key = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -25591,6 +28282,161 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_VAR_HANDLER(ZE
 	return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_UNUSED != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = NULL;
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_UNUSED == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = NULL;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_VAR != IS_UNUSED) {
+		zend_free_op free_op2;
+		zval *key = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -25860,6 +28706,160 @@ static int ZEND_FASTCALL  ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE
 	}
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_UNUSED != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = NULL;
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_UNUSED == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = NULL;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_UNUSED != IS_UNUSED) {
+
+		zval *key = NULL;
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -27016,6 +30016,160 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER(ZEN
 	return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_UNUSED != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = NULL;
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = NULL;
+
+				if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_UNUSED == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = NULL;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CV != IS_UNUSED) {
+
+		zval *key = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_BW_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -30382,6 +33536,160 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND
 	return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_CV != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+
+				if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_CV == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CONST != IS_UNUSED) {
+
+		zval *key = opline->op2.zv;
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -32180,6 +35488,160 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER(ZEND_O
 	return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_CV != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+
+				if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_CV == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zend_free_op free_op2;
+		zval *key = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -34357,6 +37819,161 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_VAR_HANDLER(ZEND_O
 	return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_CV != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+
+				if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_CV == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_VAR != IS_UNUSED) {
+		zend_free_op free_op2;
+		zval *key = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -35202,6 +38819,160 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
 	ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_CV != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+
+				if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_CV == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_UNUSED != IS_UNUSED) {
+
+		zval *key = NULL;
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
@@ -37048,6 +40819,160 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER(ZEND_OP
 	return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* The generator object is stored in return_value_ptr_ptr */
+	zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+		zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+	}
+
+	/* Destroy the previously yielded value */
+	if (generator->value) {
+		zval_ptr_dtor(&generator->value);
+	}
+
+	/* Destroy the previously yielded key */
+	if (generator->key) {
+		zval_ptr_dtor(&generator->key);
+	}
+
+	/* Set the new yielded value */
+	if (IS_CV != IS_UNUSED) {
+
+
+		if (EX(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) {
+				zval *value, *copy;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+
+				if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+					zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+				}
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				if (IS_CV == IS_VAR && !Z_ISREF_PP(value_ptr)
+				    && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+				         && EX_T(opline->op1.var).var.fcall_returned_reference)
+				    && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+					zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				} else {
+					SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+					Z_ADDREF_PP(value_ptr);
+					generator->value = *value_ptr;
+				}
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+				|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+			) {
+				zval *copy;
+
+				ALLOC_ZVAL(copy);
+				INIT_PZVAL_COPY(copy, value);
+
+				/* Temporary variables don't need ctor copying */
+				if (!0) {
+					zval_copy_ctor(copy);
+				}
+
+				generator->value = copy;
+			} else {
+				Z_ADDREF_P(value);
+				generator->value = value;
+			}
+
+		}
+	} else {
+		/* If no value was specified yield null */
+		Z_ADDREF(EG(uninitialized_zval));
+		generator->value = &EG(uninitialized_zval);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CV != IS_UNUSED) {
+
+		zval *key = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+
+		/* Consts, temporary variables and references need copying */
+		if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+			|| (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+		) {
+			zval *copy;
+
+			ALLOC_ZVAL(copy);
+			INIT_PZVAL_COPY(copy, key);
+
+			/* Temporary variables don't need ctor copying */
+			if (!0) {
+				zval_copy_ctor(copy);
+			}
+
+			generator->key = copy;
+		} else {
+			Z_ADDREF_P(key);
+			generator->key = key;
+		}
+
+		if (Z_TYPE_P(generator->key) == IS_LONG
+		    && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+		}
+
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+
+		ALLOC_INIT_ZVAL(generator->key);
+		ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+	}
+
+	/* If a value is sent it should go into the result var */
+	generator->send_target = &EX_T(opline->result.var);
+
+	/* Initialize the sent value to NULL */
+	Z_ADDREF(EG(uninitialized_zval));
+	AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
+
+	/* We increment to the next op, so we are at the correct position when the
+	 * generator is resumed. */
+	ZEND_VM_INC_OPCODE();
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
 static int ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_error_noreturn(E_ERROR, "Invalid opcode %d/%d/%d.", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);
@@ -41057,6 +44982,56 @@ void zend_init_opcodes_handlers(void)
   	ZEND_LEAVE_SPEC_HANDLER,
   	ZEND_LEAVE_SPEC_HANDLER,
   	ZEND_LEAVE_SPEC_HANDLER,
+  	ZEND_YIELD_SPEC_CONST_CONST_HANDLER,
+  	ZEND_YIELD_SPEC_CONST_TMP_HANDLER,
+  	ZEND_YIELD_SPEC_CONST_VAR_HANDLER,
+  	ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER,
+  	ZEND_YIELD_SPEC_CONST_CV_HANDLER,
+  	ZEND_YIELD_SPEC_TMP_CONST_HANDLER,
+  	ZEND_YIELD_SPEC_TMP_TMP_HANDLER,
+  	ZEND_YIELD_SPEC_TMP_VAR_HANDLER,
+  	ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER,
+  	ZEND_YIELD_SPEC_TMP_CV_HANDLER,
+  	ZEND_YIELD_SPEC_VAR_CONST_HANDLER,
+  	ZEND_YIELD_SPEC_VAR_TMP_HANDLER,
+  	ZEND_YIELD_SPEC_VAR_VAR_HANDLER,
+  	ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER,
+  	ZEND_YIELD_SPEC_VAR_CV_HANDLER,
+  	ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER,
+  	ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER,
+  	ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER,
+  	ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER,
+  	ZEND_YIELD_SPEC_UNUSED_CV_HANDLER,
+  	ZEND_YIELD_SPEC_CV_CONST_HANDLER,
+  	ZEND_YIELD_SPEC_CV_TMP_HANDLER,
+  	ZEND_YIELD_SPEC_CV_VAR_HANDLER,
+  	ZEND_YIELD_SPEC_CV_UNUSED_HANDLER,
+  	ZEND_YIELD_SPEC_CV_CV_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+  	ZEND_GENERATOR_RETURN_SPEC_HANDLER,
   	ZEND_NULL_HANDLER
   };
   zend_opcode_handlers = (opcode_handler_t*)labels;
diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl
index 0c5e8a3c9c0df..58e5631c953c6 100644
--- a/Zend/zend_vm_execute.skl
+++ b/Zend/zend_vm_execute.skl
@@ -1,31 +1,42 @@
 {%DEFINES%}
 
-ZEND_API void {%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC)
-{
-	DCL_OPLINE
+zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC) {
 	zend_execute_data *execute_data;
-	zend_bool nested = 0;
-	{%HELPER_VARS%}
-	{%EXECUTION_STATUS%}
 
-	{%INTERNAL_LABELS%}
-
-	if (EG(exception)) {
-		return;
+	/*
+	 * When allocating the execute_data, memory for compiled variables and
+	 * temporary variables is also allocated after the actual zend_execute_data
+	 * struct. op_array->last_var specifies the number of compiled variables and
+	 * op_array->T is the number of temporary variables. If there is no symbol
+	 * table, then twice as much memory is allocated for compiled variables.
+	 * In that case the first half contains zval**s and the second half the
+	 * actual zval*s (which would otherwise be in the symbol table).
+	 */
+	size_t execute_data_size = ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data));
+	size_t CVs_size = ZEND_MM_ALIGNED_SIZE(sizeof(zval **) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2));
+	size_t Ts_size = ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T;
+	size_t total_size = execute_data_size + CVs_size + Ts_size;
+
+	/*
+	 * Normally the execute_data is allocated on the VM stack (because it does
+	 * not actually do any allocation and thus is faster). For generators
+	 * though this behavior would be suboptimal, because the (rather large)
+	 * structure would have to be copied back and forth every time execution is
+	 * suspended or resumed. That's why for generators the execution context
+	 * is allocated using emalloc, thus allowing to save and restore it simply
+	 * by replacing a pointer.
+	 */
+	if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
+		execute_data = emalloc(total_size);
+	} else {
+		execute_data = zend_vm_stack_alloc(total_size TSRMLS_CC);
 	}
 
-	EG(in_execution) = 1;
+	EX(CVs) = (zval ***) ((char *) execute_data + execute_data_size);
+	memset(EX(CVs), 0, sizeof(zval **) * op_array->last_var);
 
-zend_vm_enter:
-	/* Initialize execute_data */
-	execute_data = (zend_execute_data *)zend_vm_stack_alloc(
-		ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) +
-		ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)) +
-		ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T TSRMLS_CC);
+	EX(Ts) = (temp_variable *) ((char *) EX(CVs) + CVs_size);
 
-	EX(CVs) = (zval***)((char*)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)));
-	memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
-	EX(Ts) = (temp_variable *)(((char*)EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)));
 	EX(fbc) = NULL;
 	EX(called_scope) = NULL;
 	EX(object) = NULL;
@@ -36,9 +47,6 @@ zend_vm_enter:
 	EG(current_execute_data) = execute_data;
 	EX(nested) = nested;
     EX(leaving) = 0;
-	nested = 1;
-
-	LOAD_REGS();
 
 	if (!op_array->run_time_cache && op_array->last_cache_slot) {
 		op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
@@ -47,10 +55,10 @@ zend_vm_enter:
 	if (op_array->this_var != -1 && EG(This)) {
  		Z_ADDREF_P(EG(This)); /* For $this pointer */
 		if (!EG(active_symbol_table)) {
-			EX_CV(op_array->this_var) = (zval**)EX_CVs() + (op_array->last_var + op_array->this_var);
-			*EX_CV(op_array->this_var) = EG(This);
+			EX(CVs)[op_array->this_var] = (zval **) EX(CVs) + op_array->last_var + op_array->this_var;
+			*EX(CVs)[op_array->this_var] = EG(This);
 		} else {
-			if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void**)&EX_CV(op_array->this_var))==FAILURE) {
+			if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void **) &EX(CVs)[op_array->this_var])==FAILURE) {
 				Z_DELREF_P(EG(This));
 			}
 		}
@@ -58,11 +66,32 @@ zend_vm_enter:
 
 	EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
 	EG(opline_ptr) = &EX(opline);
-	LOAD_OPLINE();
 
 	EX(function_state).function = (zend_function *) op_array;
 	EX(function_state).arguments = NULL;
 
+	return execute_data;
+}
+
+ZEND_API void {%EXECUTOR_NAME%}_ex(zend_execute_data *execute_data TSRMLS_DC)
+{
+	DCL_OPLINE
+	zend_bool original_in_execution;
+
+	{%HELPER_VARS%}
+
+	{%INTERNAL_LABELS%}
+
+	if (EG(exception)) {
+		return;
+	}
+
+	original_in_execution = EG(in_execution);
+	EG(in_execution) = 1;
+
+	LOAD_REGS();
+	LOAD_OPLINE();
+
 	while (1) {
     {%ZEND_VM_CONTINUE_LABEL%}
 #ifdef ZEND_WIN32
@@ -79,6 +108,13 @@ zend_vm_enter:
 	zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
 }
 
+ZEND_API void {%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC)
+{
+	zend_execute_data *execute_data = zend_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC);
+
+	{%EXECUTOR_NAME%}_ex(execute_data TSRMLS_CC);
+}
+
 {%EXTERNAL_EXECUTOR%}
 
 void {%INITIALIZER_NAME%}(void)
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index fde1baf90bcc8..ee2b0b2f2da27 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -856,7 +856,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
 							out($f,"#define LOAD_REGS()                do {Ts = EX(Ts); CVs = EX(CVs);} while (0)\n");
 							out($f,"#define ZEND_VM_CONTINUE() goto zend_vm_continue\n");
 							out($f,"#define ZEND_VM_RETURN()   EG(in_execution) = original_in_execution; return\n");
-							out($f,"#define ZEND_VM_ENTER()    op_array = EG(active_op_array); goto zend_vm_enter\n");
+							out($f,"#define ZEND_VM_ENTER()    execute_data = zend_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC); LOAD_REGS(); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
 							out($f,"#define ZEND_VM_LEAVE()    ZEND_VM_CONTINUE()\n");
 							out($f,"#define ZEND_VM_DISPATCH(opcode, opline) dispatch_handler = zend_vm_get_opcode_handler(opcode, opline); goto zend_vm_dispatch;\n\n");
 							out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n");
@@ -892,7 +892,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
 							out($f,"#define LOAD_REGS()                do {Ts = EX(Ts); CVs = EX(CVs);} while (0)\n");
 							out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(OPLINE->handler)\n");
 							out($f,"#define ZEND_VM_RETURN()   EG(in_execution) = original_in_execution; return\n");
-							out($f,"#define ZEND_VM_ENTER()    op_array = EG(active_op_array); goto zend_vm_enter\n");
+							out($f,"#define ZEND_VM_ENTER()    execute_data = zend_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC); LOAD_REGS(); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
 							out($f,"#define ZEND_VM_LEAVE()    ZEND_VM_CONTINUE()\n");
 							out($f,"#define ZEND_VM_DISPATCH(opcode, opline) goto *(void**)(zend_vm_get_opcode_handler(opcode, opline));\n\n");
 							out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n");
@@ -927,19 +927,12 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
 						skip_blanks($f, $m[1], $m[3]."\n");
 					}
 					break;
-				case "EXECUTION_STATUS":
-					if ($kind != ZEND_VM_KIND_GOTO) {
-						out($f, $m[1] . "zend_bool original_in_execution = EG(in_execution);\n");
-					} else {
-						out($f, $m[1] . "zend_bool original_in_execution = op_array? EG(in_execution) : 0;\n");
-					}
-					break;
 				case "INTERNAL_LABELS":
 					if ($kind == ZEND_VM_KIND_GOTO) {
 					  // Emit array of labels of opcode handlers and code for
 					  // zend_opcode_handlers initialization
 						$prolog = $m[1];
-						out($f,$prolog."if (op_array == NULL) {\n");
+						out($f,$prolog."if (execute_data == NULL) {\n");
 						out($f,$prolog."\tstatic const opcode_handler_t labels[] = {\n");
 						gen_labels($f, $spec, $kind, $prolog."\t\t");
 						out($f,$prolog."\t};\n");
@@ -983,10 +976,11 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
 						        $m[1]."\t\tEG(in_execution) = original_in_execution;\n".
 						        $m[1]."\t\treturn;\n".
 						        $m[1]."\tcase 2:\n" . 
-						        $m[1]."\t\top_array = EG(active_op_array);\n".
-						        $m[1]."\t\tgoto zend_vm_enter;\n".
+						        $m[1]."\t\texecute_data = zend_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC);\n".
+						        $m[1]."\t\tbreak;\n" .
 						        $m[1]."\tcase 3:\n" . 
 						        $m[1]."\t\texecute_data = EG(current_execute_data);\n".
+						        $m[1]."\t\tbreak;\n" .
 						        $m[1]."\tdefault:\n".
 						        $m[1]."\t\tbreak;\n".
 						        $m[1]."}".$m[3]."\n");
@@ -1013,9 +1007,9 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
 					$prolog = $m[1];
 					if ($kind == ZEND_VM_KIND_GOTO) {
 					  // Labels are defined in the executor itself, so we call it
-					  // with op_array NULL and it sets zend_opcode_handlers array
+					  // with execute_data NULL and it sets zend_opcode_handlers array
 						out($f,$prolog."TSRMLS_FETCH();\n");
-						out($f,$prolog."zend_execute(NULL TSRMLS_CC);\n");
+						out($f,$prolog.$executor_name."_ex(NULL TSRMLS_CC);\n");
 					} else {
 						if ($old) {
 						  // Reserving space for user-defined opcodes
@@ -1189,7 +1183,7 @@ function gen_vm($def, $skel) {
 
 	// Generate opcode #defines (zend_vm_opcodes.h)
 	$code_len = strlen((string)$max_opcode);
-	$f = fopen("zend_vm_opcodes.h", "w+") or die("ERROR: Cannot create zend_vm_opcodes.h\n");
+	$f = fopen(__DIR__ . "/zend_vm_opcodes.h", "w+") or die("ERROR: Cannot create zend_vm_opcodes.h\n");
 
 	// Insert header
 	out($f, $GLOBALS['header_text']);
@@ -1203,8 +1197,8 @@ function gen_vm($def, $skel) {
 	echo "zend_vm_opcodes.h generated successfully.\n";
 
 	// Generate zend_vm_execute.h
-	$f = fopen("zend_vm_execute.h", "w+") or die("ERROR: Cannot create zend_vm_execute.h\n");
-	$executor_file = realpath("zend_vm_execute.h");
+	$f = fopen(__DIR__ . "/zend_vm_execute.h", "w+") or die("ERROR: Cannot create zend_vm_execute.h\n");
+	$executor_file = realpath(__DIR__ . "/zend_vm_execute.h");
 
 	// Insert header
 	out($f, $GLOBALS['header_text']);
@@ -1447,6 +1441,6 @@ function usage() {
 	define("ZEND_VM_LINES", 0);
 }
 
-gen_vm("zend_vm_def.h", "zend_vm_execute.skl");
+gen_vm(__DIR__ . "/zend_vm_def.h", __DIR__ . "/zend_vm_execute.skl");
 
 ?>
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index 69603d1d13889..7f9434995483e 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -160,3 +160,5 @@
 #define ZEND_QM_ASSIGN_VAR                   157
 #define ZEND_JMP_SET_VAR                     158
 #define ZEND_LEAVE                           159
+#define ZEND_YIELD                           160
+#define ZEND_GENERATOR_RETURN                161
diff --git a/configure.in b/configure.in
index 529ff58eb8758..704801ec32f37 100644
--- a/configure.in
+++ b/configure.in
@@ -1472,7 +1472,7 @@ PHP_ADD_SOURCES(Zend, \
     zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
     zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
     zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
-    zend_closures.c zend_float.c zend_string.c zend_signal.c)
+    zend_closures.c zend_float.c zend_string.c zend_signal.c zend_generators.c)
 
 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
   PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_default_classes.c)
diff --git a/ext/standard/url_scanner_ex.c b/ext/standard/url_scanner_ex.c
index d106d95a36d81..dc33b96b8fe9e 100644
--- a/ext/standard/url_scanner_ex.c
+++ b/ext/standard/url_scanner_ex.c
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Sun Jan  1 10:36:29 2012 */
+/* Generated by re2c 0.13.5 on Tue May 15 13:07:17 2012 */
 #line 1 "ext/standard/url_scanner_ex.re"
 /*
   +----------------------------------------------------------------------+
diff --git a/ext/tokenizer/tests/token_get_all_variation11.phpt b/ext/tokenizer/tests/token_get_all_variation11.phpt
index ecc86177a4dfb..98d89961b77bd 100644
--- a/ext/tokenizer/tests/token_get_all_variation11.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation11.phpt
@@ -130,7 +130,7 @@ array(49) {
   [6]=>
   array(3) {
     [0]=>
-    int(283)
+    int(%d)
     [1]=>
     string(2) "=="
     [2]=>
@@ -273,7 +273,7 @@ array(49) {
   [27]=>
   array(3) {
     [0]=>
-    int(283)
+    int(%d)
     [1]=>
     string(2) "=="
     [2]=>
diff --git a/ext/tokenizer/tests/token_get_all_variation13.phpt b/ext/tokenizer/tests/token_get_all_variation13.phpt
index 9b2f3bc94fb61..6f85492a99a7f 100644
--- a/ext/tokenizer/tests/token_get_all_variation13.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation13.phpt
@@ -1005,7 +1005,7 @@ array(145) {
   [122]=>
   array(3) {
     [0]=>
-    int(288)
+    int(%d)
     [1]=>
     string(10) "instanceof"
     [2]=>
diff --git a/ext/tokenizer/tests/token_get_all_variation17.phpt b/ext/tokenizer/tests/token_get_all_variation17.phpt
index dccc4c9c23dd9..f71444bc1e84d 100644
--- a/ext/tokenizer/tests/token_get_all_variation17.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation17.phpt
@@ -145,7 +145,7 @@ array(81) {
   [14]=>
   array(3) {
     [0]=>
-    int(283)
+    int(%d)
     [1]=>
     string(2) "=="
     [2]=>
diff --git a/ext/tokenizer/tests/token_get_all_variation4.phpt b/ext/tokenizer/tests/token_get_all_variation4.phpt
index 45e6f8afbdefe..6bc111efbac25 100644
--- a/ext/tokenizer/tests/token_get_all_variation4.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation4.phpt
@@ -339,7 +339,7 @@ array(89) {
   [38]=>
   array(3) {
     [0]=>
-    int(279)
+    int(%d)
     [1]=>
     string(2) "&&"
     [2]=>
@@ -518,7 +518,7 @@ array(89) {
   [60]=>
   array(3) {
     [0]=>
-    int(278)
+    int(%d)
     [1]=>
     string(2) "||"
     [2]=>
diff --git a/ext/tokenizer/tests/token_get_all_variation5.phpt b/ext/tokenizer/tests/token_get_all_variation5.phpt
index 0068f2866fb36..681fb48e573ff 100644
--- a/ext/tokenizer/tests/token_get_all_variation5.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation5.phpt
@@ -181,7 +181,7 @@ array(94) {
   [18]=>
   array(3) {
     [0]=>
-    int(277)
+    int(%d)
     [1]=>
     string(2) "+="
     [2]=>
@@ -238,7 +238,7 @@ array(94) {
   [25]=>
   array(3) {
     [0]=>
-    int(276)
+    int(%d)
     [1]=>
     string(2) "-="
     [2]=>
@@ -295,7 +295,7 @@ array(94) {
   [32]=>
   array(3) {
     [0]=>
-    int(275)
+    int(%d)
     [1]=>
     string(2) "*="
     [2]=>
@@ -352,7 +352,7 @@ array(94) {
   [39]=>
   array(3) {
     [0]=>
-    int(274)
+    int(%d)
     [1]=>
     string(2) "/="
     [2]=>
@@ -409,7 +409,7 @@ array(94) {
   [46]=>
   array(3) {
     [0]=>
-    int(272)
+    int(%d)
     [1]=>
     string(2) "%="
     [2]=>
@@ -466,7 +466,7 @@ array(94) {
   [53]=>
   array(3) {
     [0]=>
-    int(271)
+    int(%d)
     [1]=>
     string(2) "&="
     [2]=>
@@ -523,7 +523,7 @@ array(94) {
   [60]=>
   array(3) {
     [0]=>
-    int(270)
+    int(%d)
     [1]=>
     string(2) "|="
     [2]=>
@@ -580,7 +580,7 @@ array(94) {
   [67]=>
   array(3) {
     [0]=>
-    int(269)
+    int(%d)
     [1]=>
     string(2) "^="
     [2]=>
@@ -637,7 +637,7 @@ array(94) {
   [74]=>
   array(3) {
     [0]=>
-    int(267)
+    int(%d)
     [1]=>
     string(3) ">>="
     [2]=>
@@ -694,7 +694,7 @@ array(94) {
   [81]=>
   array(3) {
     [0]=>
-    int(268)
+    int(%d)
     [1]=>
     string(3) "<<="
     [2]=>
@@ -751,7 +751,7 @@ array(94) {
   [88]=>
   array(3) {
     [0]=>
-    int(273)
+    int(%d)
     [1]=>
     string(2) ".="
     [2]=>
diff --git a/ext/tokenizer/tests/token_get_all_variation6.phpt b/ext/tokenizer/tests/token_get_all_variation6.phpt
index 54936d0c89ac3..6213dab9d0522 100644
--- a/ext/tokenizer/tests/token_get_all_variation6.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation6.phpt
@@ -191,7 +191,7 @@ array(50) {
   [21]=>
   array(3) {
     [0]=>
-    int(287)
+    int(%d)
     [1]=>
     string(2) "<<"
     [2]=>
@@ -277,7 +277,7 @@ array(50) {
   [32]=>
   array(3) {
     [0]=>
-    int(286)
+    int(%d)
     [1]=>
     string(2) ">>"
     [2]=>
diff --git a/ext/tokenizer/tests/token_get_all_variation8.phpt b/ext/tokenizer/tests/token_get_all_variation8.phpt
index 0cf1d63471127..c80a5d0f04d5a 100644
--- a/ext/tokenizer/tests/token_get_all_variation8.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation8.phpt
@@ -794,7 +794,7 @@ array(108) {
   [103]=>
   array(3) {
     [0]=>
-    int(289)
+    int(%d)
     [1]=>
     string(7) "(unset)"
     [2]=>
diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c
index a915bb8eacca0..c1b3e57662414 100644
--- a/ext/tokenizer/tokenizer_data.c
+++ b/ext/tokenizer/tokenizer_data.c
@@ -108,6 +108,7 @@ void tokenizer_register_constants(INIT_FUNC_ARGS) {
 	REGISTER_LONG_CONSTANT("T_FUNCTION", T_FUNCTION, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("T_CONST", T_CONST, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("T_RETURN", T_RETURN, CONST_CS | CONST_PERSISTENT);
+	REGISTER_LONG_CONSTANT("T_YIELD", T_YIELD, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("T_TRY", T_TRY, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("T_CATCH", T_CATCH, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("T_FINALLY", T_FINALLY, CONST_CS | CONST_PERSISTENT);
@@ -243,6 +244,7 @@ char *get_token_type_name(int token_type)
 		case T_FUNCTION: return "T_FUNCTION";
 		case T_CONST: return "T_CONST";
 		case T_RETURN: return "T_RETURN";
+		case T_YIELD: return "T_YIELD";
 		case T_TRY: return "T_TRY";
 		case T_CATCH: return "T_CATCH";
 		case T_FINALLY: return "T_FINALLY";
diff --git a/tests/lang/foreachLoop.008.phpt b/tests/lang/foreachLoop.008.phpt
deleted file mode 100644
index 787f43b88375b..0000000000000
--- a/tests/lang/foreachLoop.008.phpt
+++ /dev/null
@@ -1,10 +0,0 @@
---TEST--
-Foreach loop tests - error case: reference to constant array, with key.
---FILE--
-<?php
-foreach (array(1,2) as $k=>&$v) {
-  var_dump($v);
-}
-?>
---EXPECTF--
-Fatal error: Cannot create references to elements of a temporary array expression in %s on line 2
diff --git a/win32/build/config.w32 b/win32/build/config.w32
index be9402a3fec65..daf019435057d 100644
--- a/win32/build/config.w32
+++ b/win32/build/config.w32
@@ -359,7 +359,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \
 	zend_stream.c zend_iterators.c zend_interfaces.c zend_objects.c \
 	zend_object_handlers.c zend_objects_API.c \
 	zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c \
-	zend_float.c zend_string.c");
+	zend_float.c zend_string.c zend_generators.c");
 
 if (VCVERS == 1200) {
 	AC_DEFINE('ZEND_DVAL_TO_LVAL_CAST_OK', 1);