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-- -&$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-- + +--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-- + '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-- +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-- +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-- +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-- +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-- + '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-- +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-- + +--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-- + +--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-- + +--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-- + +--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-- + +--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-- + +--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-- +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-- + +--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-- +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-- +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-- +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-- + +--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-- + 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-- +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-- +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-- +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-- +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-- + +--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-- +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-- +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-- +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-- +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-- + +--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-- +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-- +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-- + +--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-- +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-- +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-- + +--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-- + 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-- +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-- +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-- +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-- + +===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-- + +--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-- + +--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-- + &$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-- +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-- +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-- +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-- +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-- + +--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-- +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 | + +----------------------------------------------------------------------+ +*/ + +/* $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 | + +----------------------------------------------------------------------+ +*/ + +/* $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; } +"yield" { + return T_YIELD; +} + "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-- -&$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);