]> granicus.if.org Git - php/commitdiff
Fix lexing of nested heredoc strings in token_get_all()
authorNikita Popov <nikic@php.net>
Fri, 30 Mar 2012 18:41:44 +0000 (20:41 +0200)
committerNikita Popov <nikic@php.net>
Sat, 31 Mar 2012 19:53:30 +0000 (21:53 +0200)
This fixes bug #60097.

Before two global variables CG(heredoc) and CG(heredoc_len) were used to
track the current heredoc label. In order to support nested heredoc
strings the *previous* heredoc label was assigned as the token value of
T_START_HEREDOC and the language_parser.y assigned that to CG(heredoc).

This created a dependency of the lexer on the parser. Thus the
token_get_all() function, which accesses the lexer directly without
also running the parser, was not able to tokenize nested heredoc strings
(and leaked memory). Same applies for the source-code highlighting
functions.

The new approach is to maintain a heredoc_label_stack in the lexer, which
contains all active heredoc labels.

As it is no longer required, T_START_HEREDOC and T_END_HEREDOC now don't
carry a token value anymore.

In order to make the work with zend_ptr_stack in this context more
convenient I added a new function zend_ptr_stack_top(), which retrieves the
top element of the stack (similar to zend_stack_top()).

12 files changed:
NEWS
Zend/zend_compile.c
Zend/zend_globals.h
Zend/zend_highlight.c
Zend/zend_language_parser.y
Zend/zend_language_scanner.c
Zend/zend_language_scanner.h
Zend/zend_language_scanner.l
Zend/zend_language_scanner_defs.h
Zend/zend_ptr_stack.h
ext/tokenizer/tests/bug60097.phpt [new file with mode: 0644]
ext/tokenizer/tokenizer.c

diff --git a/NEWS b/NEWS
index 089d080355715371f0711be546469c632565db0f..9382f957dd4357e4f3de1cf516e4283bdb4f4dff 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -41,4 +41,7 @@ PHP                                                                        NEWS
 - pgsql
   . Added pg_escape_literal() and pg_escape_identifier() (Yasuo)
 
+- Tokenizer:
+  . Fixed bug #60097 (token_get_all fails to lex nested heredoc). (Nikita Popov)
+
 <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>
index c3c35eb5fc6a0e9d0e5943d0e38708d4ad5f8fe6..0533bf8c180f27223740cb47edb6d7d6686feddc 100644 (file)
@@ -6708,9 +6708,6 @@ again:
                case T_OPEN_TAG_WITH_ECHO:
                        retval = T_ECHO;
                        break;
-               case T_END_HEREDOC:
-                       efree(Z_STRVAL(zendlval->u.constant));
-                       break;
        }
 
        INIT_PZVAL(&zendlval->u.constant);
index dbbcf972a441b00c4ea68a9f29c3faa176af8ea6..e5aba0df6783dcefe98b8cec3a7d989720279ae8 100644 (file)
@@ -89,9 +89,6 @@ struct _zend_compiler_globals {
 
        int zend_lineno;
 
-       char *heredoc;
-       int heredoc_len;
-
        zend_op_array *active_op_array;
 
        HashTable *function_table;      /* function symbol table */
@@ -297,6 +294,7 @@ struct _zend_php_scanner_globals {
        unsigned char *yy_limit;
        int yy_state;
        zend_stack state_stack;
+       zend_ptr_stack heredoc_label_stack;
        
        /* original (unfiltered) script */
        unsigned char *script_org;
index e9fd850e6b0f500f76902b59625e7f143753a5fe..938e1c612b91218f24f5f1a8b9b3a2400fa801c5 100644 (file)
@@ -153,8 +153,6 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
                                        efree(token.value.str.val);
                                        break;
                        }
-               } else if (token_type == T_END_HEREDOC) {
-                       efree(token.value.str.val);
                }
                token.type = 0;
        }
index d0730b75d6d4533422630df7aa68afff5e53d6d3..47c046b44f5f98a81a9d45a23af98a84c67ee6d6 100644 (file)
@@ -911,8 +911,8 @@ common_scalar:
        |       T_METHOD_C                                      { $$ = $1; }
        |       T_FUNC_C                                        { $$ = $1; }
        |       T_NS_C                                          { $$ = $1; }
-       |       T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $$ = $2; CG(heredoc) = Z_STRVAL($1.u.constant); CG(heredoc_len) = Z_STRLEN($1.u.constant); }
-       |       T_START_HEREDOC T_END_HEREDOC { ZVAL_EMPTY_STRING(&$$.u.constant); INIT_PZVAL(&$$.u.constant); $$.op_type = IS_CONST; CG(heredoc) = Z_STRVAL($1.u.constant); CG(heredoc_len) = Z_STRLEN($1.u.constant); }
+       |       T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $$ = $2; }
+       |       T_START_HEREDOC T_END_HEREDOC { ZVAL_EMPTY_STRING(&$$.u.constant); INIT_PZVAL(&$$.u.constant); $$.op_type = IS_CONST; }
 ;
 
 
@@ -941,7 +941,7 @@ scalar:
        |       T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRLEN($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_RT, 0 TSRMLS_CC); }
        |       common_scalar                   { $$ = $1; }
        |       '"' encaps_list '"'     { $$ = $2; }
-       |       T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; CG(heredoc) = Z_STRVAL($1.u.constant); CG(heredoc_len) = Z_STRLEN($1.u.constant); }
+       |       T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; }
        |       T_CLASS_C                               { if (Z_TYPE($1.u.constant) == IS_CONSTANT) {zend_do_fetch_constant(&$$, NULL, &$1, ZEND_RT, 1 TSRMLS_CC);} else {$$ = $1;} }
 ;
 
index 3f6189efeea9cd303b472879f56fee9eaa50863a..8e5cc9f9d6a0074590ca9c780bafa7174f2ce690 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Thu Mar  1 21:27:30 2012 */
+/* Generated by re2c 0.13.5 on Sat Mar 31 21:29:29 2012 */
 #line 1 "Zend/zend_language_scanner.l"
 /*
    +----------------------------------------------------------------------+
@@ -177,22 +177,23 @@ static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
 void startup_scanner(TSRMLS_D)
 {
        CG(parse_error) = 0;
-       CG(heredoc) = NULL;
-       CG(heredoc_len) = 0;
        CG(doc_comment) = NULL;
        CG(doc_comment_len) = 0;
        zend_stack_init(&SCNG(state_stack));
+       zend_ptr_stack_init(&SCNG(heredoc_label_stack));
+}
+
+static void heredoc_label_dtor(zend_heredoc_label *heredoc_label) {
+    efree(heredoc_label->label);
 }
 
 void shutdown_scanner(TSRMLS_D)
 {
-       if (CG(heredoc)) {
-               efree(CG(heredoc));
-               CG(heredoc_len)=0;
-       }
        CG(parse_error) = 0;
-       zend_stack_destroy(&SCNG(state_stack));
        RESET_DOC_COMMENT();
+       zend_stack_destroy(&SCNG(state_stack));
+       zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1);
+       zend_ptr_stack_destroy(&SCNG(heredoc_label_stack));
 }
 
 ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
@@ -207,6 +208,9 @@ ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
        lex_state->state_stack = SCNG(state_stack);
        zend_stack_init(&SCNG(state_stack));
 
+       lex_state->heredoc_label_stack = SCNG(heredoc_label_stack);
+       zend_ptr_stack_init(&SCNG(heredoc_label_stack));
+
        lex_state->in = SCNG(yy_in);
        lex_state->yy_state = YYSTATE;
        lex_state->filename = zend_get_compiled_filename(TSRMLS_C);
@@ -233,6 +237,10 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
        zend_stack_destroy(&SCNG(state_stack));
        SCNG(state_stack) = lex_state->state_stack;
 
+       zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1);
+       zend_ptr_stack_destroy(&SCNG(heredoc_label_stack));
+       SCNG(heredoc_label_stack) = lex_state->heredoc_label_stack;
+
        SCNG(yy_in) = lex_state->in;
        YYSETCONDITION(lex_state->yy_state);
        CG(zend_lineno) = lex_state->lineno;
@@ -249,12 +257,6 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
        SCNG(input_filter) = lex_state->input_filter;
        SCNG(output_filter) = lex_state->output_filter;
        SCNG(script_encoding) = lex_state->script_encoding;
-
-       if (CG(heredoc)) {
-               efree(CG(heredoc));
-               CG(heredoc) = NULL;
-               CG(heredoc_len) = 0;
-       }
 }
 
 ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle TSRMLS_DC)
@@ -991,7 +993,7 @@ restart:
 yymore_restart:
 
 
-#line 995 "Zend/zend_language_scanner.c"
+#line 997 "Zend/zend_language_scanner.c"
 {
        YYCTYPE yych;
        unsigned int yyaccept = 0;
@@ -1090,7 +1092,7 @@ yyc_INITIAL:
 yy3:
                YYDEBUG(3, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1783 "Zend/zend_language_scanner.l"
+#line 1785 "Zend/zend_language_scanner.l"
                {
        if (YYCURSOR > YYLIMIT) {
                return 0;
@@ -1150,7 +1152,7 @@ inline_html:
        HANDLE_NEWLINES(yytext, yyleng);
        return T_INLINE_HTML;
 }
-#line 1154 "Zend/zend_language_scanner.c"
+#line 1156 "Zend/zend_language_scanner.c"
 yy4:
                YYDEBUG(4, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -1168,7 +1170,7 @@ yy5:
 yy6:
                YYDEBUG(6, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1771 "Zend/zend_language_scanner.l"
+#line 1773 "Zend/zend_language_scanner.l"
                {
        if (CG(short_tags)) {
                zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1180,14 +1182,14 @@ yy6:
                goto inline_char_handler;
        }
 }
-#line 1184 "Zend/zend_language_scanner.c"
+#line 1186 "Zend/zend_language_scanner.c"
 yy7:
                YYDEBUG(7, *YYCURSOR);
                ++YYCURSOR;
                if ((yych = *YYCURSOR) == '=') goto yy43;
                YYDEBUG(8, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1748 "Zend/zend_language_scanner.l"
+#line 1750 "Zend/zend_language_scanner.l"
                {
        if (CG(asp_tags)) {
                zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1199,7 +1201,7 @@ yy7:
                goto inline_char_handler;
        }
 }
-#line 1203 "Zend/zend_language_scanner.c"
+#line 1205 "Zend/zend_language_scanner.c"
 yy9:
                YYDEBUG(9, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -1385,7 +1387,7 @@ yy35:
                ++YYCURSOR;
                YYDEBUG(38, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1708 "Zend/zend_language_scanner.l"
+#line 1710 "Zend/zend_language_scanner.l"
                {
        YYCTYPE *bracket = (YYCTYPE*)zend_memrchr(yytext, '<', yyleng - (sizeof("script language=php>") - 1));
 
@@ -1402,7 +1404,7 @@ yy35:
        BEGIN(ST_IN_SCRIPTING);
        return T_OPEN_TAG;
 }
-#line 1406 "Zend/zend_language_scanner.c"
+#line 1408 "Zend/zend_language_scanner.c"
 yy39:
                YYDEBUG(39, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -1429,7 +1431,7 @@ yy43:
                ++YYCURSOR;
                YYDEBUG(44, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1726 "Zend/zend_language_scanner.l"
+#line 1728 "Zend/zend_language_scanner.l"
                {
        if (CG(asp_tags)) {
                zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1441,13 +1443,13 @@ yy43:
                goto inline_char_handler;
        }
 }
-#line 1445 "Zend/zend_language_scanner.c"
+#line 1447 "Zend/zend_language_scanner.c"
 yy45:
                YYDEBUG(45, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(46, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1739 "Zend/zend_language_scanner.l"
+#line 1741 "Zend/zend_language_scanner.l"
                {
        zendlval->value.str.val = yytext; /* no copying - intentional */
        zendlval->value.str.len = yyleng;
@@ -1455,7 +1457,7 @@ yy45:
        BEGIN(ST_IN_SCRIPTING);
        return T_OPEN_TAG_WITH_ECHO;
 }
-#line 1459 "Zend/zend_language_scanner.c"
+#line 1461 "Zend/zend_language_scanner.c"
 yy47:
                YYDEBUG(47, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -1482,7 +1484,7 @@ yy50:
 yy51:
                YYDEBUG(51, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1761 "Zend/zend_language_scanner.l"
+#line 1763 "Zend/zend_language_scanner.l"
                {
        zendlval->value.str.val = yytext; /* no copying - intentional */
        zendlval->value.str.len = yyleng;
@@ -1491,7 +1493,7 @@ yy51:
        BEGIN(ST_IN_SCRIPTING);
        return T_OPEN_TAG;
 }
-#line 1495 "Zend/zend_language_scanner.c"
+#line 1497 "Zend/zend_language_scanner.c"
 yy52:
                YYDEBUG(52, *YYCURSOR);
                ++YYCURSOR;
@@ -1562,7 +1564,7 @@ yyc_ST_BACKQUOTE:
 yy56:
                YYDEBUG(56, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2234 "Zend/zend_language_scanner.l"
+#line 2236 "Zend/zend_language_scanner.l"
                {
        if (YYCURSOR > YYLIMIT) {
                return 0;
@@ -1603,7 +1605,7 @@ yy56:
        zend_scan_escape_string(zendlval, yytext, yyleng, '`' TSRMLS_CC);
        return T_ENCAPSED_AND_WHITESPACE;
 }
-#line 1607 "Zend/zend_language_scanner.c"
+#line 1609 "Zend/zend_language_scanner.c"
 yy57:
                YYDEBUG(57, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -1614,12 +1616,12 @@ yy58:
                ++YYCURSOR;
                YYDEBUG(59, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2178 "Zend/zend_language_scanner.l"
+#line 2180 "Zend/zend_language_scanner.l"
                {
        BEGIN(ST_IN_SCRIPTING);
        return '`';
 }
-#line 1623 "Zend/zend_language_scanner.c"
+#line 1625 "Zend/zend_language_scanner.c"
 yy60:
                YYDEBUG(60, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -1629,14 +1631,14 @@ yy61:
                ++YYCURSOR;
                YYDEBUG(62, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2165 "Zend/zend_language_scanner.l"
+#line 2167 "Zend/zend_language_scanner.l"
                {
        zendlval->value.lval = (long) '{';
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
        yyless(1);
        return T_CURLY_OPEN;
 }
-#line 1640 "Zend/zend_language_scanner.c"
+#line 1642 "Zend/zend_language_scanner.c"
 yy63:
                YYDEBUG(63, *YYCURSOR);
                yyaccept = 0;
@@ -1652,24 +1654,24 @@ yy63:
 yy65:
                YYDEBUG(65, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1865 "Zend/zend_language_scanner.l"
+#line 1867 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
        return T_VARIABLE;
 }
-#line 1662 "Zend/zend_language_scanner.c"
+#line 1664 "Zend/zend_language_scanner.c"
 yy66:
                YYDEBUG(66, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(67, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1442 "Zend/zend_language_scanner.l"
+#line 1444 "Zend/zend_language_scanner.l"
                {
        yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
        return T_DOLLAR_OPEN_CURLY_BRACES;
 }
-#line 1673 "Zend/zend_language_scanner.c"
+#line 1675 "Zend/zend_language_scanner.c"
 yy68:
                YYDEBUG(68, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -1683,7 +1685,7 @@ yy70:
                ++YYCURSOR;
                YYDEBUG(71, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1857 "Zend/zend_language_scanner.l"
+#line 1859 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 1);
        yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -1691,7 +1693,7 @@ yy70:
        zendlval->type = IS_STRING;
        return T_VARIABLE;
 }
-#line 1695 "Zend/zend_language_scanner.c"
+#line 1697 "Zend/zend_language_scanner.c"
 yy72:
                YYDEBUG(72, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -1709,7 +1711,7 @@ yy73:
                ++YYCURSOR;
                YYDEBUG(74, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1847 "Zend/zend_language_scanner.l"
+#line 1849 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 3);
        yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -1717,7 +1719,7 @@ yy73:
        zendlval->type = IS_STRING;
        return T_VARIABLE;
 }
-#line 1721 "Zend/zend_language_scanner.c"
+#line 1723 "Zend/zend_language_scanner.c"
        }
 /* *********************************** */
 yyc_ST_DOUBLE_QUOTES:
@@ -1785,7 +1787,7 @@ yy77:
 yy78:
                YYDEBUG(78, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2184 "Zend/zend_language_scanner.l"
+#line 2186 "Zend/zend_language_scanner.l"
                {
        if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) {
                YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1;
@@ -1834,7 +1836,7 @@ double_quotes_scan_done:
        zend_scan_escape_string(zendlval, yytext, yyleng, '"' TSRMLS_CC);
        return T_ENCAPSED_AND_WHITESPACE;
 }
-#line 1838 "Zend/zend_language_scanner.c"
+#line 1840 "Zend/zend_language_scanner.c"
 yy79:
                YYDEBUG(79, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -1845,12 +1847,12 @@ yy80:
                ++YYCURSOR;
                YYDEBUG(81, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2173 "Zend/zend_language_scanner.l"
+#line 2175 "Zend/zend_language_scanner.l"
                {
        BEGIN(ST_IN_SCRIPTING);
        return '"';
 }
-#line 1854 "Zend/zend_language_scanner.c"
+#line 1856 "Zend/zend_language_scanner.c"
 yy82:
                YYDEBUG(82, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -1860,14 +1862,14 @@ yy83:
                ++YYCURSOR;
                YYDEBUG(84, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2165 "Zend/zend_language_scanner.l"
+#line 2167 "Zend/zend_language_scanner.l"
                {
        zendlval->value.lval = (long) '{';
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
        yyless(1);
        return T_CURLY_OPEN;
 }
-#line 1871 "Zend/zend_language_scanner.c"
+#line 1873 "Zend/zend_language_scanner.c"
 yy85:
                YYDEBUG(85, *YYCURSOR);
                yyaccept = 0;
@@ -1883,24 +1885,24 @@ yy85:
 yy87:
                YYDEBUG(87, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1865 "Zend/zend_language_scanner.l"
+#line 1867 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
        return T_VARIABLE;
 }
-#line 1893 "Zend/zend_language_scanner.c"
+#line 1895 "Zend/zend_language_scanner.c"
 yy88:
                YYDEBUG(88, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(89, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1442 "Zend/zend_language_scanner.l"
+#line 1444 "Zend/zend_language_scanner.l"
                {
        yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
        return T_DOLLAR_OPEN_CURLY_BRACES;
 }
-#line 1904 "Zend/zend_language_scanner.c"
+#line 1906 "Zend/zend_language_scanner.c"
 yy90:
                YYDEBUG(90, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -1914,7 +1916,7 @@ yy92:
                ++YYCURSOR;
                YYDEBUG(93, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1857 "Zend/zend_language_scanner.l"
+#line 1859 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 1);
        yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -1922,7 +1924,7 @@ yy92:
        zendlval->type = IS_STRING;
        return T_VARIABLE;
 }
-#line 1926 "Zend/zend_language_scanner.c"
+#line 1928 "Zend/zend_language_scanner.c"
 yy94:
                YYDEBUG(94, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -1940,7 +1942,7 @@ yy95:
                ++YYCURSOR;
                YYDEBUG(96, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1847 "Zend/zend_language_scanner.l"
+#line 1849 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 3);
        yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -1948,7 +1950,7 @@ yy95:
        zendlval->type = IS_STRING;
        return T_VARIABLE;
 }
-#line 1952 "Zend/zend_language_scanner.c"
+#line 1954 "Zend/zend_language_scanner.c"
        }
 /* *********************************** */
 yyc_ST_END_HEREDOC:
@@ -1959,19 +1961,20 @@ yyc_ST_END_HEREDOC:
        ++YYCURSOR;
        YYDEBUG(100, *YYCURSOR);
        yyleng = YYCURSOR - SCNG(yy_text);
-#line 2152 "Zend/zend_language_scanner.l"
+#line 2153 "Zend/zend_language_scanner.l"
        {
-       YYCURSOR += CG(heredoc_len) - 1;
-       yyleng = CG(heredoc_len);
+       zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack));
+
+       YYCURSOR += heredoc_label->length - 1;
+       yyleng = heredoc_label->length;
+
+       heredoc_label_dtor(heredoc_label);
+       efree(heredoc_label);
 
-       Z_STRVAL_P(zendlval) = CG(heredoc);
-       Z_STRLEN_P(zendlval) = CG(heredoc_len);
-       CG(heredoc) = NULL;
-       CG(heredoc_len) = 0;
        BEGIN(ST_IN_SCRIPTING);
        return T_END_HEREDOC;
 }
-#line 1975 "Zend/zend_language_scanner.c"
+#line 1978 "Zend/zend_language_scanner.c"
 /* *********************************** */
 yyc_ST_HEREDOC:
        {
@@ -2033,10 +2036,12 @@ yy103:
 yy104:
                YYDEBUG(104, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2276 "Zend/zend_language_scanner.l"
+#line 2278 "Zend/zend_language_scanner.l"
                {
        int newline = 0;
 
+       zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
+
        if (YYCURSOR > YYLIMIT) {
                return 0;
        }
@@ -2052,8 +2057,8 @@ yy104:
                                /* fall through */
                        case '\n':
                                /* Check for ending label on the next line */
-                               if (IS_LABEL_START(*YYCURSOR) && CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, CG(heredoc), CG(heredoc_len))) {
-                                       YYCTYPE *end = YYCURSOR + CG(heredoc_len);
+                               if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) {
+                                       YYCTYPE *end = YYCURSOR + heredoc_label->length;
 
                                        if (*end == ';') {
                                                end++;
@@ -2104,7 +2109,7 @@ heredoc_scan_done:
        zend_scan_escape_string(zendlval, yytext, yyleng - newline, 0 TSRMLS_CC);
        return T_ENCAPSED_AND_WHITESPACE;
 }
-#line 2108 "Zend/zend_language_scanner.c"
+#line 2113 "Zend/zend_language_scanner.c"
 yy105:
                YYDEBUG(105, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -2119,14 +2124,14 @@ yy107:
                ++YYCURSOR;
                YYDEBUG(108, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2165 "Zend/zend_language_scanner.l"
+#line 2167 "Zend/zend_language_scanner.l"
                {
        zendlval->value.lval = (long) '{';
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
        yyless(1);
        return T_CURLY_OPEN;
 }
-#line 2130 "Zend/zend_language_scanner.c"
+#line 2135 "Zend/zend_language_scanner.c"
 yy109:
                YYDEBUG(109, *YYCURSOR);
                yyaccept = 0;
@@ -2142,24 +2147,24 @@ yy109:
 yy111:
                YYDEBUG(111, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1865 "Zend/zend_language_scanner.l"
+#line 1867 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
        return T_VARIABLE;
 }
-#line 2152 "Zend/zend_language_scanner.c"
+#line 2157 "Zend/zend_language_scanner.c"
 yy112:
                YYDEBUG(112, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(113, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1442 "Zend/zend_language_scanner.l"
+#line 1444 "Zend/zend_language_scanner.l"
                {
        yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
        return T_DOLLAR_OPEN_CURLY_BRACES;
 }
-#line 2163 "Zend/zend_language_scanner.c"
+#line 2168 "Zend/zend_language_scanner.c"
 yy114:
                YYDEBUG(114, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -2173,7 +2178,7 @@ yy116:
                ++YYCURSOR;
                YYDEBUG(117, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1857 "Zend/zend_language_scanner.l"
+#line 1859 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 1);
        yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -2181,7 +2186,7 @@ yy116:
        zendlval->type = IS_STRING;
        return T_VARIABLE;
 }
-#line 2185 "Zend/zend_language_scanner.c"
+#line 2190 "Zend/zend_language_scanner.c"
 yy118:
                YYDEBUG(118, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -2199,7 +2204,7 @@ yy119:
                ++YYCURSOR;
                YYDEBUG(120, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1847 "Zend/zend_language_scanner.l"
+#line 1849 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 3);
        yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -2207,7 +2212,7 @@ yy119:
        zendlval->type = IS_STRING;
        return T_VARIABLE;
 }
-#line 2211 "Zend/zend_language_scanner.c"
+#line 2216 "Zend/zend_language_scanner.c"
        }
 /* *********************************** */
 yyc_ST_IN_SCRIPTING:
@@ -2388,13 +2393,13 @@ yy123:
 yy124:
                YYDEBUG(124, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1888 "Zend/zend_language_scanner.l"
+#line 1890 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, yytext, yyleng);
        zendlval->type = IS_STRING;
        return T_STRING;
 }
-#line 2398 "Zend/zend_language_scanner.c"
+#line 2403 "Zend/zend_language_scanner.c"
 yy125:
                YYDEBUG(125, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -2620,11 +2625,11 @@ yy137:
 yy138:
                YYDEBUG(138, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1431 "Zend/zend_language_scanner.l"
+#line 1433 "Zend/zend_language_scanner.l"
                {
        return yytext[0];
 }
-#line 2628 "Zend/zend_language_scanner.c"
+#line 2633 "Zend/zend_language_scanner.c"
 yy139:
                YYDEBUG(139, *YYCURSOR);
                ++YYCURSOR;
@@ -2633,7 +2638,7 @@ yy139:
 yy140:
                YYDEBUG(140, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1162 "Zend/zend_language_scanner.l"
+#line 1164 "Zend/zend_language_scanner.l"
                {
        zendlval->value.str.val = yytext; /* no copying - intentional */
        zendlval->value.str.len = yyleng;
@@ -2641,7 +2646,7 @@ yy140:
        HANDLE_NEWLINES(yytext, yyleng);
        return T_WHITESPACE;
 }
-#line 2645 "Zend/zend_language_scanner.c"
+#line 2650 "Zend/zend_language_scanner.c"
 yy141:
                YYDEBUG(141, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -2652,11 +2657,11 @@ yy142:
                ++YYCURSOR;
                YYDEBUG(143, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1191 "Zend/zend_language_scanner.l"
+#line 1193 "Zend/zend_language_scanner.l"
                {
        return T_NS_SEPARATOR;
 }
-#line 2660 "Zend/zend_language_scanner.c"
+#line 2665 "Zend/zend_language_scanner.c"
 yy144:
                YYDEBUG(144, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -2884,18 +2889,18 @@ yy167:
                ++YYCURSOR;
                YYDEBUG(168, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1436 "Zend/zend_language_scanner.l"
+#line 1438 "Zend/zend_language_scanner.l"
                {
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
        return '{';
 }
-#line 2893 "Zend/zend_language_scanner.c"
+#line 2898 "Zend/zend_language_scanner.c"
 yy169:
                YYDEBUG(169, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(170, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1448 "Zend/zend_language_scanner.l"
+#line 1450 "Zend/zend_language_scanner.l"
                {
        RESET_DOC_COMMENT();
        if (!zend_stack_is_empty(&SCNG(state_stack))) {
@@ -2903,7 +2908,7 @@ yy169:
        }
        return '}';
 }
-#line 2907 "Zend/zend_language_scanner.c"
+#line 2912 "Zend/zend_language_scanner.c"
 yy171:
                YYDEBUG(171, *YYCURSOR);
                yyaccept = 2;
@@ -2931,7 +2936,7 @@ yy171:
 yy172:
                YYDEBUG(172, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1498 "Zend/zend_language_scanner.l"
+#line 1500 "Zend/zend_language_scanner.l"
                {
        if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */
                zendlval->value.lval = strtol(yytext, NULL, 0);
@@ -2952,7 +2957,7 @@ yy172:
        zendlval->type = IS_LONG;
        return T_LNUMBER;
 }
-#line 2956 "Zend/zend_language_scanner.c"
+#line 2961 "Zend/zend_language_scanner.c"
 yy173:
                YYDEBUG(173, *YYCURSOR);
                yyaccept = 2;
@@ -2980,7 +2985,7 @@ yy175:
 yy176:
                YYDEBUG(176, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1895 "Zend/zend_language_scanner.l"
+#line 1897 "Zend/zend_language_scanner.l"
                {
        while (YYCURSOR < YYLIMIT) {
                switch (*YYCURSOR++) {
@@ -3014,14 +3019,14 @@ yy176:
 
        return T_COMMENT;
 }
-#line 3018 "Zend/zend_language_scanner.c"
+#line 3023 "Zend/zend_language_scanner.c"
 yy177:
                YYDEBUG(177, *YYCURSOR);
                ++YYCURSOR;
 yy178:
                YYDEBUG(178, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1986 "Zend/zend_language_scanner.l"
+#line 1988 "Zend/zend_language_scanner.l"
                {
        register char *s, *t;
        char *end;
@@ -3089,14 +3094,14 @@ yy178:
        }
        return T_CONSTANT_ENCAPSED_STRING;
 }
-#line 3093 "Zend/zend_language_scanner.c"
+#line 3098 "Zend/zend_language_scanner.c"
 yy179:
                YYDEBUG(179, *YYCURSOR);
                ++YYCURSOR;
 yy180:
                YYDEBUG(180, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2055 "Zend/zend_language_scanner.l"
+#line 2057 "Zend/zend_language_scanner.l"
                {
        int bprefix = (yytext[0] != '"') ? 1 : 0;
 
@@ -3137,24 +3142,24 @@ yy180:
        BEGIN(ST_DOUBLE_QUOTES);
        return '"';
 }
-#line 3141 "Zend/zend_language_scanner.c"
+#line 3146 "Zend/zend_language_scanner.c"
 yy181:
                YYDEBUG(181, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(182, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2146 "Zend/zend_language_scanner.l"
+#line 2147 "Zend/zend_language_scanner.l"
                {
        BEGIN(ST_BACKQUOTE);
        return '`';
 }
-#line 3152 "Zend/zend_language_scanner.c"
+#line 3157 "Zend/zend_language_scanner.c"
 yy183:
                YYDEBUG(183, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(184, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2404 "Zend/zend_language_scanner.l"
+#line 2410 "Zend/zend_language_scanner.l"
                {
        if (YYCURSOR > YYLIMIT) {
                return 0;
@@ -3163,7 +3168,7 @@ yy183:
        zend_error(E_COMPILE_WARNING,"Unexpected character in input:  '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
        goto restart;
 }
-#line 3167 "Zend/zend_language_scanner.c"
+#line 3172 "Zend/zend_language_scanner.c"
 yy185:
                YYDEBUG(185, *YYCURSOR);
                ++YYCURSOR;
@@ -3190,13 +3195,13 @@ yy187:
 yy189:
                YYDEBUG(189, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1563 "Zend/zend_language_scanner.l"
+#line 1565 "Zend/zend_language_scanner.l"
                {
        zendlval->value.dval = zend_strtod(yytext, NULL);
        zendlval->type = IS_DOUBLE;
        return T_DNUMBER;
 }
-#line 3200 "Zend/zend_language_scanner.c"
+#line 3205 "Zend/zend_language_scanner.c"
 yy190:
                YYDEBUG(190, *YYCURSOR);
                yyaccept = 2;
@@ -3288,7 +3293,7 @@ yy199:
                }
                YYDEBUG(201, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1473 "Zend/zend_language_scanner.l"
+#line 1475 "Zend/zend_language_scanner.l"
                {
        char *bin = yytext + 2; /* Skip "0b" */
        int len = yyleng - 2;
@@ -3313,7 +3318,7 @@ yy199:
                return T_DNUMBER;
        }
 }
-#line 3317 "Zend/zend_language_scanner.c"
+#line 3322 "Zend/zend_language_scanner.c"
 yy202:
                YYDEBUG(202, *YYCURSOR);
                ++YYCURSOR;
@@ -3325,7 +3330,7 @@ yy202:
                }
                YYDEBUG(204, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1519 "Zend/zend_language_scanner.l"
+#line 1521 "Zend/zend_language_scanner.l"
                {
        char *hex = yytext + 2; /* Skip "0x" */
        int len = yyleng - 2;
@@ -3350,7 +3355,7 @@ yy202:
                return T_DNUMBER;
        }
 }
-#line 3354 "Zend/zend_language_scanner.c"
+#line 3359 "Zend/zend_language_scanner.c"
 yy205:
                YYDEBUG(205, *YYCURSOR);
                ++YYCURSOR;
@@ -3359,7 +3364,7 @@ yy205:
 yy206:
                YYDEBUG(206, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1963 "Zend/zend_language_scanner.l"
+#line 1965 "Zend/zend_language_scanner.l"
                {
        zendlval->value.str.val = yytext; /* no copying - intentional */
        zendlval->value.str.len = yyleng;
@@ -3367,7 +3372,7 @@ yy206:
        BEGIN(INITIAL);
        return T_CLOSE_TAG;  /* implicit ';' at php-end tag */
 }
-#line 3371 "Zend/zend_language_scanner.c"
+#line 3376 "Zend/zend_language_scanner.c"
 yy207:
                YYDEBUG(207, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -3401,13 +3406,13 @@ yy209:
 yy211:
                YYDEBUG(211, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1865 "Zend/zend_language_scanner.l"
+#line 1867 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
        return T_VARIABLE;
 }
-#line 3411 "Zend/zend_language_scanner.c"
+#line 3416 "Zend/zend_language_scanner.c"
 yy212:
                YYDEBUG(212, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -3421,11 +3426,11 @@ yy213:
                }
                YYDEBUG(214, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1419 "Zend/zend_language_scanner.l"
+#line 1421 "Zend/zend_language_scanner.l"
                {
        return T_LOGICAL_XOR;
 }
-#line 3429 "Zend/zend_language_scanner.c"
+#line 3434 "Zend/zend_language_scanner.c"
 yy215:
                YYDEBUG(215, *YYCURSOR);
                ++YYCURSOR;
@@ -3434,61 +3439,61 @@ yy215:
                }
                YYDEBUG(216, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1411 "Zend/zend_language_scanner.l"
+#line 1413 "Zend/zend_language_scanner.l"
                {
        return T_LOGICAL_OR;
 }
-#line 3442 "Zend/zend_language_scanner.c"
+#line 3447 "Zend/zend_language_scanner.c"
 yy217:
                YYDEBUG(217, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(218, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1399 "Zend/zend_language_scanner.l"
+#line 1401 "Zend/zend_language_scanner.l"
                {
        return T_XOR_EQUAL;
 }
-#line 3452 "Zend/zend_language_scanner.c"
+#line 3457 "Zend/zend_language_scanner.c"
 yy219:
                YYDEBUG(219, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(220, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1403 "Zend/zend_language_scanner.l"
+#line 1405 "Zend/zend_language_scanner.l"
                {
        return T_BOOLEAN_OR;
 }
-#line 3462 "Zend/zend_language_scanner.c"
+#line 3467 "Zend/zend_language_scanner.c"
 yy221:
                YYDEBUG(221, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(222, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1395 "Zend/zend_language_scanner.l"
+#line 1397 "Zend/zend_language_scanner.l"
                {
        return T_OR_EQUAL;
 }
-#line 3472 "Zend/zend_language_scanner.c"
+#line 3477 "Zend/zend_language_scanner.c"
 yy223:
                YYDEBUG(223, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(224, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1407 "Zend/zend_language_scanner.l"
+#line 1409 "Zend/zend_language_scanner.l"
                {
        return T_BOOLEAN_AND;
 }
-#line 3482 "Zend/zend_language_scanner.c"
+#line 3487 "Zend/zend_language_scanner.c"
 yy225:
                YYDEBUG(225, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(226, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1391 "Zend/zend_language_scanner.l"
+#line 1393 "Zend/zend_language_scanner.l"
                {
        return T_AND_EQUAL;
 }
-#line 3492 "Zend/zend_language_scanner.c"
+#line 3497 "Zend/zend_language_scanner.c"
 yy227:
                YYDEBUG(227, *YYCURSOR);
                ++YYCURSOR;
@@ -3497,7 +3502,7 @@ yy227:
 yy228:
                YYDEBUG(228, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1972 "Zend/zend_language_scanner.l"
+#line 1974 "Zend/zend_language_scanner.l"
                {
        if (CG(asp_tags)) {
                BEGIN(INITIAL);
@@ -3510,17 +3515,17 @@ yy228:
                return yytext[0];
        }
 }
-#line 3514 "Zend/zend_language_scanner.c"
+#line 3519 "Zend/zend_language_scanner.c"
 yy229:
                YYDEBUG(229, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(230, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1379 "Zend/zend_language_scanner.l"
+#line 1381 "Zend/zend_language_scanner.l"
                {
        return T_MOD_EQUAL;
 }
-#line 3524 "Zend/zend_language_scanner.c"
+#line 3529 "Zend/zend_language_scanner.c"
 yy231:
                YYDEBUG(231, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -3551,11 +3556,11 @@ yy235:
                ++YYCURSOR;
                YYDEBUG(236, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1375 "Zend/zend_language_scanner.l"
+#line 1377 "Zend/zend_language_scanner.l"
                {
        return T_CONCAT_EQUAL;
 }
-#line 3559 "Zend/zend_language_scanner.c"
+#line 3564 "Zend/zend_language_scanner.c"
 yy237:
                YYDEBUG(237, *YYCURSOR);
                yyaccept = 4;
@@ -3564,7 +3569,7 @@ yy237:
 yy238:
                YYDEBUG(238, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1929 "Zend/zend_language_scanner.l"
+#line 1931 "Zend/zend_language_scanner.l"
                {
        int doc_com;
 
@@ -3598,7 +3603,7 @@ yy238:
 
        return T_COMMENT;
 }
-#line 3602 "Zend/zend_language_scanner.c"
+#line 3607 "Zend/zend_language_scanner.c"
 yy239:
                YYDEBUG(239, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -3608,11 +3613,11 @@ yy240:
                ++YYCURSOR;
                YYDEBUG(241, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1371 "Zend/zend_language_scanner.l"
+#line 1373 "Zend/zend_language_scanner.l"
                {
        return T_DIV_EQUAL;
 }
-#line 3616 "Zend/zend_language_scanner.c"
+#line 3621 "Zend/zend_language_scanner.c"
 yy242:
                YYDEBUG(242, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -3635,42 +3640,42 @@ yy245:
                ++YYCURSOR;
                YYDEBUG(246, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1367 "Zend/zend_language_scanner.l"
+#line 1369 "Zend/zend_language_scanner.l"
                {
        return T_MUL_EQUAL;
 }
-#line 3643 "Zend/zend_language_scanner.c"
+#line 3648 "Zend/zend_language_scanner.c"
 yy247:
                YYDEBUG(247, *YYCURSOR);
                ++YYCURSOR;
                if ((yych = *YYCURSOR) == '=') goto yy251;
                YYDEBUG(248, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1427 "Zend/zend_language_scanner.l"
+#line 1429 "Zend/zend_language_scanner.l"
                {
        return T_SR;
 }
-#line 3654 "Zend/zend_language_scanner.c"
+#line 3659 "Zend/zend_language_scanner.c"
 yy249:
                YYDEBUG(249, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(250, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1355 "Zend/zend_language_scanner.l"
+#line 1357 "Zend/zend_language_scanner.l"
                {
        return T_IS_GREATER_OR_EQUAL;
 }
-#line 3664 "Zend/zend_language_scanner.c"
+#line 3669 "Zend/zend_language_scanner.c"
 yy251:
                YYDEBUG(251, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(252, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1387 "Zend/zend_language_scanner.l"
+#line 1389 "Zend/zend_language_scanner.l"
                {
        return T_SR_EQUAL;
 }
-#line 3674 "Zend/zend_language_scanner.c"
+#line 3679 "Zend/zend_language_scanner.c"
 yy253:
                YYDEBUG(253, *YYCURSOR);
                yyaccept = 5;
@@ -3681,11 +3686,11 @@ yy253:
 yy254:
                YYDEBUG(254, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1423 "Zend/zend_language_scanner.l"
+#line 1425 "Zend/zend_language_scanner.l"
                {
        return T_SL;
 }
-#line 3689 "Zend/zend_language_scanner.c"
+#line 3694 "Zend/zend_language_scanner.c"
 yy255:
                YYDEBUG(255, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -3697,22 +3702,22 @@ yy256:
                ++YYCURSOR;
                YYDEBUG(257, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1351 "Zend/zend_language_scanner.l"
+#line 1353 "Zend/zend_language_scanner.l"
                {
        return T_IS_SMALLER_OR_EQUAL;
 }
-#line 3705 "Zend/zend_language_scanner.c"
+#line 3710 "Zend/zend_language_scanner.c"
 yy258:
                YYDEBUG(258, *YYCURSOR);
                ++YYCURSOR;
 yy259:
                YYDEBUG(259, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1347 "Zend/zend_language_scanner.l"
+#line 1349 "Zend/zend_language_scanner.l"
                {
        return T_IS_NOT_EQUAL;
 }
-#line 3716 "Zend/zend_language_scanner.c"
+#line 3721 "Zend/zend_language_scanner.c"
 yy260:
                YYDEBUG(260, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -3763,11 +3768,11 @@ yy267:
                ++YYCURSOR;
                YYDEBUG(268, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1383 "Zend/zend_language_scanner.l"
+#line 1385 "Zend/zend_language_scanner.l"
                {
        return T_SL_EQUAL;
 }
-#line 3771 "Zend/zend_language_scanner.c"
+#line 3776 "Zend/zend_language_scanner.c"
 yy269:
                YYDEBUG(269, *YYCURSOR);
                ++YYCURSOR;
@@ -3872,42 +3877,39 @@ yy278:
 yy279:
                YYDEBUG(279, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2097 "Zend/zend_language_scanner.l"
+#line 2099 "Zend/zend_language_scanner.l"
                {
        char *s;
        int bprefix = (yytext[0] != '<') ? 1 : 0;
-
-       /* save old heredoc label */
-       Z_STRVAL_P(zendlval) = CG(heredoc);
-       Z_STRLEN_P(zendlval) = CG(heredoc_len);
+       zend_heredoc_label *heredoc_label = emalloc(sizeof(zend_heredoc_label));
 
        CG(zend_lineno)++;
-       CG(heredoc_len) = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0);
+       heredoc_label->length = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0);
        s = yytext+bprefix+3;
        while ((*s == ' ') || (*s == '\t')) {
                s++;
-               CG(heredoc_len)--;
+               heredoc_label->length--;
        }
 
        if (*s == '\'') {
                s++;
-               CG(heredoc_len) -= 2;
+               heredoc_label->length -= 2;
 
                BEGIN(ST_NOWDOC);
        } else {
                if (*s == '"') {
                        s++;
-                       CG(heredoc_len) -= 2;
+                       heredoc_label->length -= 2;
                }
 
                BEGIN(ST_HEREDOC);
        }
 
-       CG(heredoc) = estrndup(s, CG(heredoc_len));
+       heredoc_label->label = estrndup(s, heredoc_label->length);
 
        /* Check for ending label on the next line */
-       if (CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, CG(heredoc_len))) {
-               YYCTYPE *end = YYCURSOR + CG(heredoc_len);
+       if (heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, heredoc_label->length)) {
+               YYCTYPE *end = YYCURSOR + heredoc_label->length;
 
                if (*end == ';') {
                        end++;
@@ -3918,9 +3920,11 @@ yy279:
                }
        }
 
+       zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) heredoc_label);
+
        return T_START_HEREDOC;
 }
-#line 3924 "Zend/zend_language_scanner.c"
+#line 3928 "Zend/zend_language_scanner.c"
 yy280:
                YYDEBUG(280, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -3960,31 +3964,31 @@ yy283:
                ++YYCURSOR;
                YYDEBUG(285, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1339 "Zend/zend_language_scanner.l"
+#line 1341 "Zend/zend_language_scanner.l"
                {
        return T_IS_NOT_IDENTICAL;
 }
-#line 3968 "Zend/zend_language_scanner.c"
+#line 3972 "Zend/zend_language_scanner.c"
 yy286:
                YYDEBUG(286, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(287, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1359 "Zend/zend_language_scanner.l"
+#line 1361 "Zend/zend_language_scanner.l"
                {
        return T_PLUS_EQUAL;
 }
-#line 3978 "Zend/zend_language_scanner.c"
+#line 3982 "Zend/zend_language_scanner.c"
 yy288:
                YYDEBUG(288, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(289, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1327 "Zend/zend_language_scanner.l"
+#line 1329 "Zend/zend_language_scanner.l"
                {
        return T_INC;
 }
-#line 3988 "Zend/zend_language_scanner.c"
+#line 3992 "Zend/zend_language_scanner.c"
 yy290:
                YYDEBUG(290, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4003,42 +4007,42 @@ yy292:
                }
                YYDEBUG(293, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1315 "Zend/zend_language_scanner.l"
+#line 1317 "Zend/zend_language_scanner.l"
                {
        return T_LIST;
 }
-#line 4011 "Zend/zend_language_scanner.c"
+#line 4015 "Zend/zend_language_scanner.c"
 yy294:
                YYDEBUG(294, *YYCURSOR);
                ++YYCURSOR;
                if ((yych = *YYCURSOR) == '=') goto yy298;
                YYDEBUG(295, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1343 "Zend/zend_language_scanner.l"
+#line 1345 "Zend/zend_language_scanner.l"
                {
        return T_IS_EQUAL;
 }
-#line 4022 "Zend/zend_language_scanner.c"
+#line 4026 "Zend/zend_language_scanner.c"
 yy296:
                YYDEBUG(296, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(297, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1311 "Zend/zend_language_scanner.l"
+#line 1313 "Zend/zend_language_scanner.l"
                {
        return T_DOUBLE_ARROW;
 }
-#line 4032 "Zend/zend_language_scanner.c"
+#line 4036 "Zend/zend_language_scanner.c"
 yy298:
                YYDEBUG(298, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(299, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1335 "Zend/zend_language_scanner.l"
+#line 1337 "Zend/zend_language_scanner.l"
                {
        return T_IS_IDENTICAL;
 }
-#line 4042 "Zend/zend_language_scanner.c"
+#line 4046 "Zend/zend_language_scanner.c"
 yy300:
                YYDEBUG(300, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4168,7 +4172,7 @@ yy316:
                }
                YYDEBUG(319, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1698 "Zend/zend_language_scanner.l"
+#line 1700 "Zend/zend_language_scanner.l"
                {
        if (CG(current_namespace)) {
                *zendlval = *CG(current_namespace);
@@ -4178,7 +4182,7 @@ yy316:
        }
        return T_NS_C;
 }
-#line 4182 "Zend/zend_language_scanner.c"
+#line 4186 "Zend/zend_language_scanner.c"
 yy320:
                YYDEBUG(320, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4198,7 +4202,7 @@ yy321:
                }
                YYDEBUG(324, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1671 "Zend/zend_language_scanner.l"
+#line 1673 "Zend/zend_language_scanner.l"
                {
        char *filename = zend_get_compiled_filename(TSRMLS_C);
        const size_t filename_len = strlen(filename);
@@ -4225,7 +4229,7 @@ yy321:
        zendlval->type = IS_STRING;
        return T_DIR;
 }
-#line 4229 "Zend/zend_language_scanner.c"
+#line 4233 "Zend/zend_language_scanner.c"
 yy325:
                YYDEBUG(325, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4250,13 +4254,13 @@ yy327:
                }
                YYDEBUG(330, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1653 "Zend/zend_language_scanner.l"
+#line 1655 "Zend/zend_language_scanner.l"
                {
        zendlval->value.lval = CG(zend_lineno);
        zendlval->type = IS_LONG;
        return T_LINE;
 }
-#line 4260 "Zend/zend_language_scanner.c"
+#line 4264 "Zend/zend_language_scanner.c"
 yy331:
                YYDEBUG(331, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4291,7 +4295,7 @@ yy335:
                }
                YYDEBUG(338, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1632 "Zend/zend_language_scanner.l"
+#line 1634 "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;
@@ -4312,7 +4316,7 @@ yy335:
        zendlval->type = IS_STRING;
        return T_METHOD_C;
 }
-#line 4316 "Zend/zend_language_scanner.c"
+#line 4320 "Zend/zend_language_scanner.c"
 yy339:
                YYDEBUG(339, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4363,7 +4367,7 @@ yy346:
                }
                YYDEBUG(349, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1616 "Zend/zend_language_scanner.l"
+#line 1618 "Zend/zend_language_scanner.l"
                {
        const char *func_name = NULL;
 
@@ -4379,7 +4383,7 @@ yy346:
        zendlval->type = IS_STRING;
        return T_FUNC_C;
 }
-#line 4383 "Zend/zend_language_scanner.c"
+#line 4387 "Zend/zend_language_scanner.c"
 yy350:
                YYDEBUG(350, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4399,7 +4403,7 @@ yy351:
                }
                YYDEBUG(354, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1659 "Zend/zend_language_scanner.l"
+#line 1661 "Zend/zend_language_scanner.l"
                {
        char *filename = zend_get_compiled_filename(TSRMLS_C);
 
@@ -4411,7 +4415,7 @@ yy351:
        zendlval->type = IS_STRING;
        return T_FILE;
 }
-#line 4415 "Zend/zend_language_scanner.c"
+#line 4419 "Zend/zend_language_scanner.c"
 yy355:
                YYDEBUG(355, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4441,7 +4445,7 @@ yy358:
                }
                YYDEBUG(361, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1596 "Zend/zend_language_scanner.l"
+#line 1598 "Zend/zend_language_scanner.l"
                {
        const char *trait_name = NULL;
        
@@ -4461,7 +4465,7 @@ yy358:
        
        return T_TRAIT_C;
 }
-#line 4465 "Zend/zend_language_scanner.c"
+#line 4469 "Zend/zend_language_scanner.c"
 yy362:
                YYDEBUG(362, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4491,7 +4495,7 @@ yy365:
                }
                YYDEBUG(368, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1569 "Zend/zend_language_scanner.l"
+#line 1571 "Zend/zend_language_scanner.l"
                {
        const char *class_name = NULL;
        
@@ -4518,7 +4522,7 @@ yy365:
        }
        return T_CLASS_C;
 }
-#line 4522 "Zend/zend_language_scanner.c"
+#line 4526 "Zend/zend_language_scanner.c"
 yy369:
                YYDEBUG(369, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4580,11 +4584,11 @@ yy380:
                }
                YYDEBUG(381, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1279 "Zend/zend_language_scanner.l"
+#line 1281 "Zend/zend_language_scanner.l"
                {
        return T_HALT_COMPILER;
 }
-#line 4588 "Zend/zend_language_scanner.c"
+#line 4592 "Zend/zend_language_scanner.c"
 yy382:
                YYDEBUG(382, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4604,11 +4608,11 @@ yy384:
                }
                YYDEBUG(385, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1259 "Zend/zend_language_scanner.l"
+#line 1261 "Zend/zend_language_scanner.l"
                {
        return T_USE;
 }
-#line 4612 "Zend/zend_language_scanner.c"
+#line 4616 "Zend/zend_language_scanner.c"
 yy386:
                YYDEBUG(386, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4627,11 +4631,11 @@ yy388:
                }
                YYDEBUG(389, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1307 "Zend/zend_language_scanner.l"
+#line 1309 "Zend/zend_language_scanner.l"
                {
        return T_UNSET;
 }
-#line 4635 "Zend/zend_language_scanner.c"
+#line 4639 "Zend/zend_language_scanner.c"
 yy390:
                YYDEBUG(390, *YYCURSOR);
                ++YYCURSOR;
@@ -4803,11 +4807,11 @@ yy405:
                ++YYCURSOR;
                YYDEBUG(407, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1207 "Zend/zend_language_scanner.l"
+#line 1209 "Zend/zend_language_scanner.l"
                {
        return T_INT_CAST;
 }
-#line 4811 "Zend/zend_language_scanner.c"
+#line 4815 "Zend/zend_language_scanner.c"
 yy408:
                YYDEBUG(408, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4851,11 +4855,11 @@ yy413:
                ++YYCURSOR;
                YYDEBUG(416, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1211 "Zend/zend_language_scanner.l"
+#line 1213 "Zend/zend_language_scanner.l"
                {
        return T_DOUBLE_CAST;
 }
-#line 4859 "Zend/zend_language_scanner.c"
+#line 4863 "Zend/zend_language_scanner.c"
 yy417:
                YYDEBUG(417, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4925,11 +4929,11 @@ yy427:
                ++YYCURSOR;
                YYDEBUG(430, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1215 "Zend/zend_language_scanner.l"
+#line 1217 "Zend/zend_language_scanner.l"
                {
        return T_STRING_CAST;
 }
-#line 4933 "Zend/zend_language_scanner.c"
+#line 4937 "Zend/zend_language_scanner.c"
 yy431:
                YYDEBUG(431, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4962,11 +4966,11 @@ yy434:
                ++YYCURSOR;
                YYDEBUG(437, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1219 "Zend/zend_language_scanner.l"
+#line 1221 "Zend/zend_language_scanner.l"
                {
        return T_ARRAY_CAST;
 }
-#line 4970 "Zend/zend_language_scanner.c"
+#line 4974 "Zend/zend_language_scanner.c"
 yy438:
                YYDEBUG(438, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5004,11 +5008,11 @@ yy442:
                ++YYCURSOR;
                YYDEBUG(445, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1223 "Zend/zend_language_scanner.l"
+#line 1225 "Zend/zend_language_scanner.l"
                {
        return T_OBJECT_CAST;
 }
-#line 5012 "Zend/zend_language_scanner.c"
+#line 5016 "Zend/zend_language_scanner.c"
 yy446:
                YYDEBUG(446, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5049,11 +5053,11 @@ yy451:
                ++YYCURSOR;
                YYDEBUG(453, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1227 "Zend/zend_language_scanner.l"
+#line 1229 "Zend/zend_language_scanner.l"
                {
        return T_BOOL_CAST;
 }
-#line 5057 "Zend/zend_language_scanner.c"
+#line 5061 "Zend/zend_language_scanner.c"
 yy454:
                YYDEBUG(454, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5113,11 +5117,11 @@ yy462:
                ++YYCURSOR;
                YYDEBUG(465, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1231 "Zend/zend_language_scanner.l"
+#line 1233 "Zend/zend_language_scanner.l"
                {
        return T_UNSET_CAST;
 }
-#line 5121 "Zend/zend_language_scanner.c"
+#line 5125 "Zend/zend_language_scanner.c"
 yy466:
                YYDEBUG(466, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5131,11 +5135,11 @@ yy467:
                }
                YYDEBUG(468, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1203 "Zend/zend_language_scanner.l"
+#line 1205 "Zend/zend_language_scanner.l"
                {
        return T_VAR;
 }
-#line 5139 "Zend/zend_language_scanner.c"
+#line 5143 "Zend/zend_language_scanner.c"
 yy469:
                YYDEBUG(469, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5155,11 +5159,11 @@ yy471:
                }
                YYDEBUG(472, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1195 "Zend/zend_language_scanner.l"
+#line 1197 "Zend/zend_language_scanner.l"
                {
        return T_NEW;
 }
-#line 5163 "Zend/zend_language_scanner.c"
+#line 5167 "Zend/zend_language_scanner.c"
 yy473:
                YYDEBUG(473, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5198,21 +5202,21 @@ yy479:
                }
                YYDEBUG(480, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1255 "Zend/zend_language_scanner.l"
+#line 1257 "Zend/zend_language_scanner.l"
                {
        return T_NAMESPACE;
 }
-#line 5206 "Zend/zend_language_scanner.c"
+#line 5210 "Zend/zend_language_scanner.c"
 yy481:
                YYDEBUG(481, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(482, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1187 "Zend/zend_language_scanner.l"
+#line 1189 "Zend/zend_language_scanner.l"
                {
        return T_PAAMAYIM_NEKUDOTAYIM;
 }
-#line 5216 "Zend/zend_language_scanner.c"
+#line 5220 "Zend/zend_language_scanner.c"
 yy483:
                YYDEBUG(483, *YYCURSOR);
                ++YYCURSOR;
@@ -5234,32 +5238,32 @@ yy485:
                ++YYCURSOR;
                YYDEBUG(486, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1363 "Zend/zend_language_scanner.l"
+#line 1365 "Zend/zend_language_scanner.l"
                {
        return T_MINUS_EQUAL;
 }
-#line 5242 "Zend/zend_language_scanner.c"
+#line 5246 "Zend/zend_language_scanner.c"
 yy487:
                YYDEBUG(487, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(488, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1331 "Zend/zend_language_scanner.l"
+#line 1333 "Zend/zend_language_scanner.l"
                {
        return T_DEC;
 }
-#line 5252 "Zend/zend_language_scanner.c"
+#line 5256 "Zend/zend_language_scanner.c"
 yy489:
                YYDEBUG(489, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(490, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1157 "Zend/zend_language_scanner.l"
+#line 1159 "Zend/zend_language_scanner.l"
                {
        yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
        return T_OBJECT_OPERATOR;
 }
-#line 5263 "Zend/zend_language_scanner.c"
+#line 5267 "Zend/zend_language_scanner.c"
 yy491:
                YYDEBUG(491, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5304,11 +5308,11 @@ yy496:
                }
                YYDEBUG(497, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1303 "Zend/zend_language_scanner.l"
+#line 1305 "Zend/zend_language_scanner.l"
                {
        return T_PUBLIC;
 }
-#line 5312 "Zend/zend_language_scanner.c"
+#line 5316 "Zend/zend_language_scanner.c"
 yy498:
                YYDEBUG(498, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5363,11 +5367,11 @@ yy505:
                }
                YYDEBUG(506, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1299 "Zend/zend_language_scanner.l"
+#line 1301 "Zend/zend_language_scanner.l"
                {
        return T_PROTECTED;
 }
-#line 5371 "Zend/zend_language_scanner.c"
+#line 5375 "Zend/zend_language_scanner.c"
 yy507:
                YYDEBUG(507, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5397,11 +5401,11 @@ yy511:
                }
                YYDEBUG(512, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1295 "Zend/zend_language_scanner.l"
+#line 1297 "Zend/zend_language_scanner.l"
                {
        return T_PRIVATE;
 }
-#line 5405 "Zend/zend_language_scanner.c"
+#line 5409 "Zend/zend_language_scanner.c"
 yy513:
                YYDEBUG(513, *YYCURSOR);
                ++YYCURSOR;
@@ -5410,11 +5414,11 @@ yy513:
                }
                YYDEBUG(514, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1133 "Zend/zend_language_scanner.l"
+#line 1135 "Zend/zend_language_scanner.l"
                {
        return T_PRINT;
 }
-#line 5418 "Zend/zend_language_scanner.c"
+#line 5422 "Zend/zend_language_scanner.c"
 yy515:
                YYDEBUG(515, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5439,11 +5443,11 @@ yy518:
                }
                YYDEBUG(519, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1125 "Zend/zend_language_scanner.l"
+#line 1127 "Zend/zend_language_scanner.l"
                {
        return T_GOTO;
 }
-#line 5447 "Zend/zend_language_scanner.c"
+#line 5451 "Zend/zend_language_scanner.c"
 yy520:
                YYDEBUG(520, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5467,11 +5471,11 @@ yy523:
                }
                YYDEBUG(524, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1267 "Zend/zend_language_scanner.l"
+#line 1269 "Zend/zend_language_scanner.l"
                {
        return T_GLOBAL;
 }
-#line 5475 "Zend/zend_language_scanner.c"
+#line 5479 "Zend/zend_language_scanner.c"
 yy525:
                YYDEBUG(525, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5508,11 +5512,11 @@ yy531:
                }
                YYDEBUG(532, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1117 "Zend/zend_language_scanner.l"
+#line 1119 "Zend/zend_language_scanner.l"
                {
        return T_BREAK;
 }
-#line 5516 "Zend/zend_language_scanner.c"
+#line 5520 "Zend/zend_language_scanner.c"
 yy533:
                YYDEBUG(533, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5552,11 +5556,11 @@ yy539:
                }
                YYDEBUG(540, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1101 "Zend/zend_language_scanner.l"
+#line 1103 "Zend/zend_language_scanner.l"
                {
        return T_SWITCH;
 }
-#line 5560 "Zend/zend_language_scanner.c"
+#line 5564 "Zend/zend_language_scanner.c"
 yy541:
                YYDEBUG(541, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5580,11 +5584,11 @@ yy544:
                }
                YYDEBUG(545, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1283 "Zend/zend_language_scanner.l"
+#line 1285 "Zend/zend_language_scanner.l"
                {
        return T_STATIC;
 }
-#line 5588 "Zend/zend_language_scanner.c"
+#line 5592 "Zend/zend_language_scanner.c"
 yy546:
                YYDEBUG(546, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5611,11 +5615,11 @@ yy549:
                }
                YYDEBUG(550, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1097 "Zend/zend_language_scanner.l"
+#line 1099 "Zend/zend_language_scanner.l"
                {
        return T_AS;
 }
-#line 5619 "Zend/zend_language_scanner.c"
+#line 5623 "Zend/zend_language_scanner.c"
 yy551:
                YYDEBUG(551, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5634,11 +5638,11 @@ yy553:
                }
                YYDEBUG(554, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1319 "Zend/zend_language_scanner.l"
+#line 1321 "Zend/zend_language_scanner.l"
                {
        return T_ARRAY;
 }
-#line 5642 "Zend/zend_language_scanner.c"
+#line 5646 "Zend/zend_language_scanner.c"
 yy555:
                YYDEBUG(555, *YYCURSOR);
                ++YYCURSOR;
@@ -5647,11 +5651,11 @@ yy555:
                }
                YYDEBUG(556, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1415 "Zend/zend_language_scanner.l"
+#line 1417 "Zend/zend_language_scanner.l"
                {
        return T_LOGICAL_AND;
 }
-#line 5655 "Zend/zend_language_scanner.c"
+#line 5659 "Zend/zend_language_scanner.c"
 yy557:
                YYDEBUG(557, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5685,11 +5689,11 @@ yy562:
                }
                YYDEBUG(563, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1287 "Zend/zend_language_scanner.l"
+#line 1289 "Zend/zend_language_scanner.l"
                {
        return T_ABSTRACT;
 }
-#line 5693 "Zend/zend_language_scanner.c"
+#line 5697 "Zend/zend_language_scanner.c"
 yy564:
                YYDEBUG(564, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5713,11 +5717,11 @@ yy567:
                }
                YYDEBUG(568, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1057 "Zend/zend_language_scanner.l"
+#line 1059 "Zend/zend_language_scanner.l"
                {
        return T_WHILE;
 }
-#line 5721 "Zend/zend_language_scanner.c"
+#line 5725 "Zend/zend_language_scanner.c"
 yy569:
                YYDEBUG(569, *YYCURSOR);
                ++YYCURSOR;
@@ -5726,11 +5730,11 @@ yy569:
                }
                YYDEBUG(570, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1041 "Zend/zend_language_scanner.l"
+#line 1043 "Zend/zend_language_scanner.l"
                {
        return T_IF;
 }
-#line 5734 "Zend/zend_language_scanner.c"
+#line 5738 "Zend/zend_language_scanner.c"
 yy571:
                YYDEBUG(571, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5782,11 +5786,11 @@ yy576:
                }
                YYDEBUG(577, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1271 "Zend/zend_language_scanner.l"
+#line 1273 "Zend/zend_language_scanner.l"
                {
        return T_ISSET;
 }
-#line 5790 "Zend/zend_language_scanner.c"
+#line 5794 "Zend/zend_language_scanner.c"
 yy578:
                YYDEBUG(578, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5840,11 +5844,11 @@ yy584:
 yy585:
                YYDEBUG(585, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1239 "Zend/zend_language_scanner.l"
+#line 1241 "Zend/zend_language_scanner.l"
                {
        return T_INCLUDE;
 }
-#line 5848 "Zend/zend_language_scanner.c"
+#line 5852 "Zend/zend_language_scanner.c"
 yy586:
                YYDEBUG(586, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5873,11 +5877,11 @@ yy590:
                }
                YYDEBUG(591, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1243 "Zend/zend_language_scanner.l"
+#line 1245 "Zend/zend_language_scanner.l"
                {
        return T_INCLUDE_ONCE;
 }
-#line 5881 "Zend/zend_language_scanner.c"
+#line 5885 "Zend/zend_language_scanner.c"
 yy592:
                YYDEBUG(592, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5911,11 +5915,11 @@ yy597:
                }
                YYDEBUG(598, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1141 "Zend/zend_language_scanner.l"
+#line 1143 "Zend/zend_language_scanner.l"
                {
        return T_INTERFACE;
 }
-#line 5919 "Zend/zend_language_scanner.c"
+#line 5923 "Zend/zend_language_scanner.c"
 yy599:
                YYDEBUG(599, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5965,11 +5969,11 @@ yy605:
                }
                YYDEBUG(606, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1263 "Zend/zend_language_scanner.l"
+#line 1265 "Zend/zend_language_scanner.l"
                {
         return T_INSTEADOF;
 }
-#line 5973 "Zend/zend_language_scanner.c"
+#line 5977 "Zend/zend_language_scanner.c"
 yy607:
                YYDEBUG(607, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5998,11 +6002,11 @@ yy611:
                }
                YYDEBUG(612, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1093 "Zend/zend_language_scanner.l"
+#line 1095 "Zend/zend_language_scanner.l"
                {
        return T_INSTANCEOF;
 }
-#line 6006 "Zend/zend_language_scanner.c"
+#line 6010 "Zend/zend_language_scanner.c"
 yy613:
                YYDEBUG(613, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6046,11 +6050,11 @@ yy620:
                }
                YYDEBUG(621, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1153 "Zend/zend_language_scanner.l"
+#line 1155 "Zend/zend_language_scanner.l"
                {
        return T_IMPLEMENTS;
 }
-#line 6054 "Zend/zend_language_scanner.c"
+#line 6058 "Zend/zend_language_scanner.c"
 yy622:
                YYDEBUG(622, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6078,11 +6082,11 @@ yy623:
                }
                YYDEBUG(625, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1029 "Zend/zend_language_scanner.l"
+#line 1031 "Zend/zend_language_scanner.l"
                {
        return T_TRY;
 }
-#line 6086 "Zend/zend_language_scanner.c"
+#line 6090 "Zend/zend_language_scanner.c"
 yy626:
                YYDEBUG(626, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6101,11 +6105,11 @@ yy628:
                }
                YYDEBUG(629, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1145 "Zend/zend_language_scanner.l"
+#line 1147 "Zend/zend_language_scanner.l"
                {
        return T_TRAIT;
 }
-#line 6109 "Zend/zend_language_scanner.c"
+#line 6113 "Zend/zend_language_scanner.c"
 yy630:
                YYDEBUG(630, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6124,11 +6128,11 @@ yy632:
                }
                YYDEBUG(633, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1037 "Zend/zend_language_scanner.l"
+#line 1039 "Zend/zend_language_scanner.l"
                {
        return T_THROW;
 }
-#line 6132 "Zend/zend_language_scanner.c"
+#line 6136 "Zend/zend_language_scanner.c"
 yy634:
                YYDEBUG(634, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6189,11 +6193,11 @@ yy640:
 yy641:
                YYDEBUG(641, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1247 "Zend/zend_language_scanner.l"
+#line 1249 "Zend/zend_language_scanner.l"
                {
        return T_REQUIRE;
 }
-#line 6197 "Zend/zend_language_scanner.c"
+#line 6201 "Zend/zend_language_scanner.c"
 yy642:
                YYDEBUG(642, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6222,11 +6226,11 @@ yy646:
                }
                YYDEBUG(647, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1251 "Zend/zend_language_scanner.l"
+#line 1253 "Zend/zend_language_scanner.l"
                {
        return T_REQUIRE_ONCE;
 }
-#line 6230 "Zend/zend_language_scanner.c"
+#line 6234 "Zend/zend_language_scanner.c"
 yy648:
                YYDEBUG(648, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6245,11 +6249,11 @@ yy650:
                }
                YYDEBUG(651, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1025 "Zend/zend_language_scanner.l"
+#line 1027 "Zend/zend_language_scanner.l"
                {
        return T_RETURN;
 }
-#line 6253 "Zend/zend_language_scanner.c"
+#line 6257 "Zend/zend_language_scanner.c"
 yy652:
                YYDEBUG(652, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6339,11 +6343,11 @@ yy661:
                }
                YYDEBUG(662, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1121 "Zend/zend_language_scanner.l"
+#line 1123 "Zend/zend_language_scanner.l"
                {
        return T_CONTINUE;
 }
-#line 6347 "Zend/zend_language_scanner.c"
+#line 6351 "Zend/zend_language_scanner.c"
 yy663:
                YYDEBUG(663, *YYCURSOR);
                ++YYCURSOR;
@@ -6352,11 +6356,11 @@ yy663:
                }
                YYDEBUG(664, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1021 "Zend/zend_language_scanner.l"
+#line 1023 "Zend/zend_language_scanner.l"
                {
        return T_CONST;
 }
-#line 6360 "Zend/zend_language_scanner.c"
+#line 6364 "Zend/zend_language_scanner.c"
 yy665:
                YYDEBUG(665, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6381,11 +6385,11 @@ yy668:
                }
                YYDEBUG(669, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1199 "Zend/zend_language_scanner.l"
+#line 1201 "Zend/zend_language_scanner.l"
                {
        return T_CLONE;
 }
-#line 6389 "Zend/zend_language_scanner.c"
+#line 6393 "Zend/zend_language_scanner.c"
 yy670:
                YYDEBUG(670, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6399,11 +6403,11 @@ yy671:
                }
                YYDEBUG(672, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1137 "Zend/zend_language_scanner.l"
+#line 1139 "Zend/zend_language_scanner.l"
                {
        return T_CLASS;
 }
-#line 6407 "Zend/zend_language_scanner.c"
+#line 6411 "Zend/zend_language_scanner.c"
 yy673:
                YYDEBUG(673, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6449,11 +6453,11 @@ yy680:
                }
                YYDEBUG(681, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1323 "Zend/zend_language_scanner.l"
+#line 1325 "Zend/zend_language_scanner.l"
                {
  return T_CALLABLE;
 }
-#line 6457 "Zend/zend_language_scanner.c"
+#line 6461 "Zend/zend_language_scanner.c"
 yy682:
                YYDEBUG(682, *YYCURSOR);
                ++YYCURSOR;
@@ -6462,11 +6466,11 @@ yy682:
                }
                YYDEBUG(683, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1109 "Zend/zend_language_scanner.l"
+#line 1111 "Zend/zend_language_scanner.l"
                {
        return T_CASE;
 }
-#line 6470 "Zend/zend_language_scanner.c"
+#line 6474 "Zend/zend_language_scanner.c"
 yy684:
                YYDEBUG(684, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6480,11 +6484,11 @@ yy685:
                }
                YYDEBUG(686, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1033 "Zend/zend_language_scanner.l"
+#line 1035 "Zend/zend_language_scanner.l"
                {
        return T_CATCH;
 }
-#line 6488 "Zend/zend_language_scanner.c"
+#line 6492 "Zend/zend_language_scanner.c"
 yy687:
                YYDEBUG(687, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6535,11 +6539,11 @@ yy695:
                }
                YYDEBUG(696, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1017 "Zend/zend_language_scanner.l"
+#line 1019 "Zend/zend_language_scanner.l"
                {
        return T_FUNCTION;
 }
-#line 6543 "Zend/zend_language_scanner.c"
+#line 6547 "Zend/zend_language_scanner.c"
 yy697:
                YYDEBUG(697, *YYCURSOR);
                ++YYCURSOR;
@@ -6563,11 +6567,11 @@ yy697:
 yy698:
                YYDEBUG(698, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1069 "Zend/zend_language_scanner.l"
+#line 1071 "Zend/zend_language_scanner.l"
                {
        return T_FOR;
 }
-#line 6571 "Zend/zend_language_scanner.c"
+#line 6575 "Zend/zend_language_scanner.c"
 yy699:
                YYDEBUG(699, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6591,11 +6595,11 @@ yy702:
                }
                YYDEBUG(703, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1077 "Zend/zend_language_scanner.l"
+#line 1079 "Zend/zend_language_scanner.l"
                {
        return T_FOREACH;
 }
-#line 6599 "Zend/zend_language_scanner.c"
+#line 6603 "Zend/zend_language_scanner.c"
 yy704:
                YYDEBUG(704, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6614,11 +6618,11 @@ yy706:
                }
                YYDEBUG(707, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1291 "Zend/zend_language_scanner.l"
+#line 1293 "Zend/zend_language_scanner.l"
                {
        return T_FINAL;
 }
-#line 6622 "Zend/zend_language_scanner.c"
+#line 6626 "Zend/zend_language_scanner.c"
 yy708:
                YYDEBUG(708, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6649,11 +6653,11 @@ yy710:
                }
                YYDEBUG(711, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1065 "Zend/zend_language_scanner.l"
+#line 1067 "Zend/zend_language_scanner.l"
                {
        return T_DO;
 }
-#line 6657 "Zend/zend_language_scanner.c"
+#line 6661 "Zend/zend_language_scanner.c"
 yy712:
                YYDEBUG(712, *YYCURSOR);
                ++YYCURSOR;
@@ -6662,11 +6666,11 @@ yy712:
                }
                YYDEBUG(713, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1013 "Zend/zend_language_scanner.l"
+#line 1015 "Zend/zend_language_scanner.l"
                {
        return T_EXIT;
 }
-#line 6670 "Zend/zend_language_scanner.c"
+#line 6674 "Zend/zend_language_scanner.c"
 yy714:
                YYDEBUG(714, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6701,11 +6705,11 @@ yy719:
                }
                YYDEBUG(720, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1113 "Zend/zend_language_scanner.l"
+#line 1115 "Zend/zend_language_scanner.l"
                {
        return T_DEFAULT;
 }
-#line 6709 "Zend/zend_language_scanner.c"
+#line 6713 "Zend/zend_language_scanner.c"
 yy721:
                YYDEBUG(721, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6729,11 +6733,11 @@ yy724:
                }
                YYDEBUG(725, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1085 "Zend/zend_language_scanner.l"
+#line 1087 "Zend/zend_language_scanner.l"
                {
        return T_DECLARE;
 }
-#line 6737 "Zend/zend_language_scanner.c"
+#line 6741 "Zend/zend_language_scanner.c"
 yy726:
                YYDEBUG(726, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6813,11 +6817,11 @@ yy737:
                }
                YYDEBUG(738, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1149 "Zend/zend_language_scanner.l"
+#line 1151 "Zend/zend_language_scanner.l"
                {
        return T_EXTENDS;
 }
-#line 6821 "Zend/zend_language_scanner.c"
+#line 6825 "Zend/zend_language_scanner.c"
 yy739:
                YYDEBUG(739, *YYCURSOR);
                ++YYCURSOR;
@@ -6826,11 +6830,11 @@ yy739:
                }
                YYDEBUG(740, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1009 "Zend/zend_language_scanner.l"
+#line 1011 "Zend/zend_language_scanner.l"
                {
        return T_EXIT;
 }
-#line 6834 "Zend/zend_language_scanner.c"
+#line 6838 "Zend/zend_language_scanner.c"
 yy741:
                YYDEBUG(741, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6844,11 +6848,11 @@ yy742:
                }
                YYDEBUG(743, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1235 "Zend/zend_language_scanner.l"
+#line 1237 "Zend/zend_language_scanner.l"
                {
        return T_EVAL;
 }
-#line 6852 "Zend/zend_language_scanner.c"
+#line 6856 "Zend/zend_language_scanner.c"
 yy744:
                YYDEBUG(744, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6918,11 +6922,11 @@ yy753:
                }
                YYDEBUG(754, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1061 "Zend/zend_language_scanner.l"
+#line 1063 "Zend/zend_language_scanner.l"
                {
        return T_ENDWHILE;
 }
-#line 6926 "Zend/zend_language_scanner.c"
+#line 6930 "Zend/zend_language_scanner.c"
 yy755:
                YYDEBUG(755, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6951,11 +6955,11 @@ yy759:
                }
                YYDEBUG(760, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1105 "Zend/zend_language_scanner.l"
+#line 1107 "Zend/zend_language_scanner.l"
                {
        return T_ENDSWITCH;
 }
-#line 6959 "Zend/zend_language_scanner.c"
+#line 6963 "Zend/zend_language_scanner.c"
 yy761:
                YYDEBUG(761, *YYCURSOR);
                ++YYCURSOR;
@@ -6964,11 +6968,11 @@ yy761:
                }
                YYDEBUG(762, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1049 "Zend/zend_language_scanner.l"
+#line 1051 "Zend/zend_language_scanner.l"
                {
        return T_ENDIF;
 }
-#line 6972 "Zend/zend_language_scanner.c"
+#line 6976 "Zend/zend_language_scanner.c"
 yy763:
                YYDEBUG(763, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6997,11 +7001,11 @@ yy764:
 yy765:
                YYDEBUG(765, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1073 "Zend/zend_language_scanner.l"
+#line 1075 "Zend/zend_language_scanner.l"
                {
        return T_ENDFOR;
 }
-#line 7005 "Zend/zend_language_scanner.c"
+#line 7009 "Zend/zend_language_scanner.c"
 yy766:
                YYDEBUG(766, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7025,11 +7029,11 @@ yy769:
                }
                YYDEBUG(770, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1081 "Zend/zend_language_scanner.l"
+#line 1083 "Zend/zend_language_scanner.l"
                {
        return T_ENDFOREACH;
 }
-#line 7033 "Zend/zend_language_scanner.c"
+#line 7037 "Zend/zend_language_scanner.c"
 yy771:
                YYDEBUG(771, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7063,11 +7067,11 @@ yy776:
                }
                YYDEBUG(777, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1089 "Zend/zend_language_scanner.l"
+#line 1091 "Zend/zend_language_scanner.l"
                {
        return T_ENDDECLARE;
 }
-#line 7071 "Zend/zend_language_scanner.c"
+#line 7075 "Zend/zend_language_scanner.c"
 yy778:
                YYDEBUG(778, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7086,11 +7090,11 @@ yy780:
                }
                YYDEBUG(781, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1275 "Zend/zend_language_scanner.l"
+#line 1277 "Zend/zend_language_scanner.l"
                {
        return T_EMPTY;
 }
-#line 7094 "Zend/zend_language_scanner.c"
+#line 7098 "Zend/zend_language_scanner.c"
 yy782:
                YYDEBUG(782, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7119,11 +7123,11 @@ yy783:
 yy784:
                YYDEBUG(784, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1053 "Zend/zend_language_scanner.l"
+#line 1055 "Zend/zend_language_scanner.l"
                {
        return T_ELSE;
 }
-#line 7127 "Zend/zend_language_scanner.c"
+#line 7131 "Zend/zend_language_scanner.c"
 yy785:
                YYDEBUG(785, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7137,11 +7141,11 @@ yy786:
                }
                YYDEBUG(787, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1045 "Zend/zend_language_scanner.l"
+#line 1047 "Zend/zend_language_scanner.l"
                {
        return T_ELSEIF;
 }
-#line 7145 "Zend/zend_language_scanner.c"
+#line 7149 "Zend/zend_language_scanner.c"
 yy788:
                YYDEBUG(788, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7155,11 +7159,11 @@ yy789:
                }
                YYDEBUG(790, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1129 "Zend/zend_language_scanner.l"
+#line 1131 "Zend/zend_language_scanner.l"
                {
        return T_ECHO;
 }
-#line 7163 "Zend/zend_language_scanner.c"
+#line 7167 "Zend/zend_language_scanner.c"
        }
 /* *********************************** */
 yyc_ST_LOOKING_FOR_PROPERTY:
@@ -7232,7 +7236,7 @@ yy793:
 yy794:
                YYDEBUG(794, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1162 "Zend/zend_language_scanner.l"
+#line 1164 "Zend/zend_language_scanner.l"
                {
        zendlval->value.str.val = yytext; /* no copying - intentional */
        zendlval->value.str.len = yyleng;
@@ -7240,7 +7244,7 @@ yy794:
        HANDLE_NEWLINES(yytext, yyleng);
        return T_WHITESPACE;
 }
-#line 7244 "Zend/zend_language_scanner.c"
+#line 7248 "Zend/zend_language_scanner.c"
 yy795:
                YYDEBUG(795, *YYCURSOR);
                ++YYCURSOR;
@@ -7248,13 +7252,13 @@ yy795:
 yy796:
                YYDEBUG(796, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1181 "Zend/zend_language_scanner.l"
+#line 1183 "Zend/zend_language_scanner.l"
                {
        yyless(0);
        yy_pop_state(TSRMLS_C);
        goto restart;
 }
-#line 7258 "Zend/zend_language_scanner.c"
+#line 7262 "Zend/zend_language_scanner.c"
 yy797:
                YYDEBUG(797, *YYCURSOR);
                ++YYCURSOR;
@@ -7263,14 +7267,14 @@ yy797:
 yy798:
                YYDEBUG(798, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1174 "Zend/zend_language_scanner.l"
+#line 1176 "Zend/zend_language_scanner.l"
                {
        yy_pop_state(TSRMLS_C);
        zend_copy_value(zendlval, yytext, yyleng);
        zendlval->type = IS_STRING;
        return T_STRING;
 }
-#line 7274 "Zend/zend_language_scanner.c"
+#line 7278 "Zend/zend_language_scanner.c"
 yy799:
                YYDEBUG(799, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7291,11 +7295,11 @@ yy802:
                ++YYCURSOR;
                YYDEBUG(803, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1170 "Zend/zend_language_scanner.l"
+#line 1172 "Zend/zend_language_scanner.l"
                {
        return T_OBJECT_OPERATOR;
 }
-#line 7299 "Zend/zend_language_scanner.c"
+#line 7303 "Zend/zend_language_scanner.c"
 yy804:
                YYDEBUG(804, *YYCURSOR);
                ++YYCURSOR;
@@ -7365,7 +7369,7 @@ yy808:
 yy809:
                YYDEBUG(809, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1457 "Zend/zend_language_scanner.l"
+#line 1459 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, yytext, yyleng);
        zendlval->type = IS_STRING;
@@ -7373,20 +7377,20 @@ yy809:
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
        return T_STRING_VARNAME;
 }
-#line 7377 "Zend/zend_language_scanner.c"
+#line 7381 "Zend/zend_language_scanner.c"
 yy810:
                YYDEBUG(810, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(811, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1466 "Zend/zend_language_scanner.l"
+#line 1468 "Zend/zend_language_scanner.l"
                {
        yyless(0);
        yy_pop_state(TSRMLS_C);
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
        goto restart;
 }
-#line 7390 "Zend/zend_language_scanner.c"
+#line 7394 "Zend/zend_language_scanner.c"
 yy812:
                YYDEBUG(812, *YYCURSOR);
                ++YYCURSOR;
@@ -7408,10 +7412,12 @@ yyc_ST_NOWDOC:
        ++YYCURSOR;
        YYDEBUG(817, *YYCURSOR);
        yyleng = YYCURSOR - SCNG(yy_text);
-#line 2348 "Zend/zend_language_scanner.l"
+#line 2352 "Zend/zend_language_scanner.l"
        {
        int newline = 0;
 
+       zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
+
        if (YYCURSOR > YYLIMIT) {
                return 0;
        }
@@ -7427,8 +7433,8 @@ yyc_ST_NOWDOC:
                                /* fall through */
                        case '\n':
                                /* Check for ending label on the next line */
-                               if (IS_LABEL_START(*YYCURSOR) && CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, CG(heredoc), CG(heredoc_len))) {
-                                       YYCTYPE *end = YYCURSOR + CG(heredoc_len);
+                               if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) {
+                                       YYCTYPE *end = YYCURSOR + heredoc_label->length;
 
                                        if (*end == ';') {
                                                end++;
@@ -7463,7 +7469,7 @@ nowdoc_scan_done:
        HANDLE_NEWLINES(yytext, yyleng - newline);
        return T_ENCAPSED_AND_WHITESPACE;
 }
-#line 7467 "Zend/zend_language_scanner.c"
+#line 7473 "Zend/zend_language_scanner.c"
 /* *********************************** */
 yyc_ST_VAR_OFFSET:
        {
@@ -7570,7 +7576,7 @@ yy820:
 yy821:
                YYDEBUG(821, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1544 "Zend/zend_language_scanner.l"
+#line 1546 "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);
@@ -7582,7 +7588,7 @@ yy821:
        }
        return T_NUM_STRING;
 }
-#line 7586 "Zend/zend_language_scanner.c"
+#line 7592 "Zend/zend_language_scanner.c"
 yy822:
                YYDEBUG(822, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7602,23 +7608,23 @@ yy823:
 yy824:
                YYDEBUG(824, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1876 "Zend/zend_language_scanner.l"
+#line 1878 "Zend/zend_language_scanner.l"
                {
        /* Only '[' can be valid, but returning other tokens will allow a more explicit parse error */
        return yytext[0];
 }
-#line 7611 "Zend/zend_language_scanner.c"
+#line 7617 "Zend/zend_language_scanner.c"
 yy825:
                YYDEBUG(825, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(826, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1871 "Zend/zend_language_scanner.l"
+#line 1873 "Zend/zend_language_scanner.l"
                {
        yy_pop_state(TSRMLS_C);
        return ']';
 }
-#line 7622 "Zend/zend_language_scanner.c"
+#line 7628 "Zend/zend_language_scanner.c"
 yy827:
                YYDEBUG(827, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7628,14 +7634,14 @@ yy828:
                ++YYCURSOR;
                YYDEBUG(829, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1881 "Zend/zend_language_scanner.l"
+#line 1883 "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 7639 "Zend/zend_language_scanner.c"
+#line 7645 "Zend/zend_language_scanner.c"
 yy830:
                YYDEBUG(830, *YYCURSOR);
                ++YYCURSOR;
@@ -7644,19 +7650,19 @@ yy830:
 yy831:
                YYDEBUG(831, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1888 "Zend/zend_language_scanner.l"
+#line 1890 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, yytext, yyleng);
        zendlval->type = IS_STRING;
        return T_STRING;
 }
-#line 7654 "Zend/zend_language_scanner.c"
+#line 7660 "Zend/zend_language_scanner.c"
 yy832:
                YYDEBUG(832, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(833, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2404 "Zend/zend_language_scanner.l"
+#line 2410 "Zend/zend_language_scanner.l"
                {
        if (YYCURSOR > YYLIMIT) {
                return 0;
@@ -7665,7 +7671,7 @@ yy832:
        zend_error(E_COMPILE_WARNING,"Unexpected character in input:  '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
        goto restart;
 }
-#line 7669 "Zend/zend_language_scanner.c"
+#line 7675 "Zend/zend_language_scanner.c"
 yy834:
                YYDEBUG(834, *YYCURSOR);
                ++YYCURSOR;
@@ -7701,13 +7707,13 @@ yy836:
 yy838:
                YYDEBUG(838, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1865 "Zend/zend_language_scanner.l"
+#line 1867 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
        return T_VARIABLE;
 }
-#line 7711 "Zend/zend_language_scanner.c"
+#line 7717 "Zend/zend_language_scanner.c"
 yy839:
                YYDEBUG(839, *YYCURSOR);
                ++YYCURSOR;
@@ -7747,14 +7753,14 @@ yy844:
 yy846:
                YYDEBUG(846, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1556 "Zend/zend_language_scanner.l"
+#line 1558 "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 7758 "Zend/zend_language_scanner.c"
+#line 7764 "Zend/zend_language_scanner.c"
 yy847:
                YYDEBUG(847, *YYCURSOR);
                ++YYCURSOR;
@@ -7777,6 +7783,6 @@ yy849:
                goto yy846;
        }
 }
-#line 2413 "Zend/zend_language_scanner.l"
+#line 2419 "Zend/zend_language_scanner.l"
 
 }
index a1a84b3bc986388fbac7d31fe2df84719fe251b5..c1a2313b2db8ed7ffa165518afaf0eaf4f13f582 100644 (file)
@@ -31,6 +31,7 @@ typedef struct _zend_lex_state {
        unsigned char *yy_limit;
        int yy_state;
        zend_stack state_stack;
+       zend_ptr_stack heredoc_label_stack;
 
        zend_file_handle *in;
        uint lineno;
@@ -50,6 +51,10 @@ typedef struct _zend_lex_state {
        const zend_encoding *script_encoding;
 } zend_lex_state;
 
+typedef struct _zend_heredoc_label {
+       char *label;
+       int length;
+} zend_heredoc_label;
 
 BEGIN_EXTERN_C()
 int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2);
index d530b53430d5e51471ba0ef198d5f6ffc4fada68..948fe0c2452140cde2a9bc6a2de7cc93c360a389 100644 (file)
@@ -175,22 +175,23 @@ static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
 void startup_scanner(TSRMLS_D)
 {
        CG(parse_error) = 0;
-       CG(heredoc) = NULL;
-       CG(heredoc_len) = 0;
        CG(doc_comment) = NULL;
        CG(doc_comment_len) = 0;
        zend_stack_init(&SCNG(state_stack));
+       zend_ptr_stack_init(&SCNG(heredoc_label_stack));
+}
+
+static void heredoc_label_dtor(zend_heredoc_label *heredoc_label) {
+    efree(heredoc_label->label);
 }
 
 void shutdown_scanner(TSRMLS_D)
 {
-       if (CG(heredoc)) {
-               efree(CG(heredoc));
-               CG(heredoc_len)=0;
-       }
        CG(parse_error) = 0;
-       zend_stack_destroy(&SCNG(state_stack));
        RESET_DOC_COMMENT();
+       zend_stack_destroy(&SCNG(state_stack));
+       zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1);
+       zend_ptr_stack_destroy(&SCNG(heredoc_label_stack));
 }
 
 ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
@@ -205,6 +206,9 @@ ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
        lex_state->state_stack = SCNG(state_stack);
        zend_stack_init(&SCNG(state_stack));
 
+       lex_state->heredoc_label_stack = SCNG(heredoc_label_stack);
+       zend_ptr_stack_init(&SCNG(heredoc_label_stack));
+
        lex_state->in = SCNG(yy_in);
        lex_state->yy_state = YYSTATE;
        lex_state->filename = zend_get_compiled_filename(TSRMLS_C);
@@ -231,6 +235,10 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
        zend_stack_destroy(&SCNG(state_stack));
        SCNG(state_stack) = lex_state->state_stack;
 
+       zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1);
+       zend_ptr_stack_destroy(&SCNG(heredoc_label_stack));
+       SCNG(heredoc_label_stack) = lex_state->heredoc_label_stack;
+
        SCNG(yy_in) = lex_state->in;
        YYSETCONDITION(lex_state->yy_state);
        CG(zend_lineno) = lex_state->lineno;
@@ -247,12 +255,6 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
        SCNG(input_filter) = lex_state->input_filter;
        SCNG(output_filter) = lex_state->output_filter;
        SCNG(script_encoding) = lex_state->script_encoding;
-
-       if (CG(heredoc)) {
-               efree(CG(heredoc));
-               CG(heredoc) = NULL;
-               CG(heredoc_len) = 0;
-       }
 }
 
 ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle TSRMLS_DC)
@@ -2097,38 +2099,35 @@ inline_html:
 <ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}({LABEL}|([']{LABEL}['])|(["]{LABEL}["])){NEWLINE} {
        char *s;
        int bprefix = (yytext[0] != '<') ? 1 : 0;
-
-       /* save old heredoc label */
-       Z_STRVAL_P(zendlval) = CG(heredoc);
-       Z_STRLEN_P(zendlval) = CG(heredoc_len);
+       zend_heredoc_label *heredoc_label = emalloc(sizeof(zend_heredoc_label));
 
        CG(zend_lineno)++;
-       CG(heredoc_len) = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0);
+       heredoc_label->length = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0);
        s = yytext+bprefix+3;
        while ((*s == ' ') || (*s == '\t')) {
                s++;
-               CG(heredoc_len)--;
+               heredoc_label->length--;
        }
 
        if (*s == '\'') {
                s++;
-               CG(heredoc_len) -= 2;
+               heredoc_label->length -= 2;
 
                BEGIN(ST_NOWDOC);
        } else {
                if (*s == '"') {
                        s++;
-                       CG(heredoc_len) -= 2;
+                       heredoc_label->length -= 2;
                }
 
                BEGIN(ST_HEREDOC);
        }
 
-       CG(heredoc) = estrndup(s, CG(heredoc_len));
+       heredoc_label->label = estrndup(s, heredoc_label->length);
 
        /* Check for ending label on the next line */
-       if (CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, CG(heredoc_len))) {
-               YYCTYPE *end = YYCURSOR + CG(heredoc_len);
+       if (heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, heredoc_label->length)) {
+               YYCTYPE *end = YYCURSOR + heredoc_label->length;
 
                if (*end == ';') {
                        end++;
@@ -2139,6 +2138,8 @@ inline_html:
                }
        }
 
+       zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) heredoc_label);
+
        return T_START_HEREDOC;
 }
 
@@ -2150,13 +2151,14 @@ inline_html:
 
 
 <ST_END_HEREDOC>{ANY_CHAR} {
-       YYCURSOR += CG(heredoc_len) - 1;
-       yyleng = CG(heredoc_len);
+       zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack));
+
+       YYCURSOR += heredoc_label->length - 1;
+       yyleng = heredoc_label->length;
+
+       heredoc_label_dtor(heredoc_label);
+       efree(heredoc_label);
 
-       Z_STRVAL_P(zendlval) = CG(heredoc);
-       Z_STRLEN_P(zendlval) = CG(heredoc_len);
-       CG(heredoc) = NULL;
-       CG(heredoc_len) = 0;
        BEGIN(ST_IN_SCRIPTING);
        return T_END_HEREDOC;
 }
@@ -2276,6 +2278,8 @@ double_quotes_scan_done:
 <ST_HEREDOC>{ANY_CHAR} {
        int newline = 0;
 
+       zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
+
        if (YYCURSOR > YYLIMIT) {
                return 0;
        }
@@ -2291,8 +2295,8 @@ double_quotes_scan_done:
                                /* fall through */
                        case '\n':
                                /* Check for ending label on the next line */
-                               if (IS_LABEL_START(*YYCURSOR) && CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, CG(heredoc), CG(heredoc_len))) {
-                                       YYCTYPE *end = YYCURSOR + CG(heredoc_len);
+                               if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) {
+                                       YYCTYPE *end = YYCURSOR + heredoc_label->length;
 
                                        if (*end == ';') {
                                                end++;
@@ -2348,6 +2352,8 @@ heredoc_scan_done:
 <ST_NOWDOC>{ANY_CHAR} {
        int newline = 0;
 
+       zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
+
        if (YYCURSOR > YYLIMIT) {
                return 0;
        }
@@ -2363,8 +2369,8 @@ heredoc_scan_done:
                                /* fall through */
                        case '\n':
                                /* Check for ending label on the next line */
-                               if (IS_LABEL_START(*YYCURSOR) && CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, CG(heredoc), CG(heredoc_len))) {
-                                       YYCTYPE *end = YYCURSOR + CG(heredoc_len);
+                               if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) {
+                                       YYCTYPE *end = YYCURSOR + heredoc_label->length;
 
                                        if (*end == ';') {
                                                end++;
index 015a903ded2d18040c34d2d9efa4bfd17ad0487a..c764903f278eba5b174bb641e1ede6fd464188e2 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Thu Mar  1 21:27:30 2012 */
+/* Generated by re2c 0.13.5 on Sat Mar 31 21:29:29 2012 */
 #line 3 "Zend/zend_language_scanner_defs.h"
 
 enum YYCONDTYPE {
index cc062de872e4ad6251fc826577adfa96da182133..9f6fc13161a8b11ea743af8b850b2eb0dcd47896 100644 (file)
@@ -111,6 +111,11 @@ static zend_always_inline void *zend_ptr_stack_pop(zend_ptr_stack *stack)
        return *(--stack->top_element);
 }
 
+static inline void *zend_ptr_stack_top(zend_ptr_stack *stack)
+{
+    return stack->elements[stack->top - 1];
+}
+
 #endif /* ZEND_PTR_STACK_H */
 
 /*
diff --git a/ext/tokenizer/tests/bug60097.phpt b/ext/tokenizer/tests/bug60097.phpt
new file mode 100644 (file)
index 0000000..620b4fd
--- /dev/null
@@ -0,0 +1,121 @@
+--TEST--
+Bug 60097: token_get_all fails to lex nested heredoc
+--FILE--
+<?php
+
+var_dump(token_get_all('<?php
+<<<DOC1
+{$s(<<<DOC2
+DOC2
+)}
+DOC1;
+'));
+
+?>
+--EXPECT--
+array(14) {
+  [0]=>
+  array(3) {
+    [0]=>
+    int(372)
+    [1]=>
+    string(6) "<?php
+"
+    [2]=>
+    int(1)
+  }
+  [1]=>
+  array(3) {
+    [0]=>
+    int(376)
+    [1]=>
+    string(8) "<<<DOC1
+"
+    [2]=>
+    int(2)
+  }
+  [2]=>
+  array(3) {
+    [0]=>
+    int(379)
+    [1]=>
+    string(1) "{"
+    [2]=>
+    int(3)
+  }
+  [3]=>
+  array(3) {
+    [0]=>
+    int(309)
+    [1]=>
+    string(2) "$s"
+    [2]=>
+    int(3)
+  }
+  [4]=>
+  string(1) "("
+  [5]=>
+  array(3) {
+    [0]=>
+    int(376)
+    [1]=>
+    string(8) "<<<DOC2
+"
+    [2]=>
+    int(3)
+  }
+  [6]=>
+  array(3) {
+    [0]=>
+    int(377)
+    [1]=>
+    string(4) "DOC2"
+    [2]=>
+    int(4)
+  }
+  [7]=>
+  array(3) {
+    [0]=>
+    int(375)
+    [1]=>
+    string(1) "
+"
+    [2]=>
+    int(4)
+  }
+  [8]=>
+  string(1) ")"
+  [9]=>
+  string(1) "}"
+  [10]=>
+  array(3) {
+    [0]=>
+    int(314)
+    [1]=>
+    string(1) "
+"
+    [2]=>
+    int(5)
+  }
+  [11]=>
+  array(3) {
+    [0]=>
+    int(377)
+    [1]=>
+    string(4) "DOC1"
+    [2]=>
+    int(6)
+  }
+  [12]=>
+  string(1) ";"
+  [13]=>
+  array(3) {
+    [0]=>
+    int(375)
+    [1]=>
+    string(1) "
+"
+    [2]=>
+    int(6)
+  }
+}
index c5cbf6c7d2f71990919e76e1aad1a788aa191336..d22fd712433808fdaeb4777ac5cc91cf536e7dd0 100644 (file)
@@ -138,11 +138,8 @@ static void tokenize(zval *return_value TSRMLS_DC)
                                        token_line = ++CG(zend_lineno);
                                        CG(increment_lineno) = 0;
                                }
-                               add_next_index_stringl(keyword, Z_STRVAL(token), Z_STRLEN(token), 1);
-                               efree(Z_STRVAL(token));
-                       } else {
-                               add_next_index_stringl(keyword, (char *)zendtext, zendleng, 1);
                        }
+                       add_next_index_stringl(keyword, (char *)zendtext, zendleng, 1);
                        add_next_index_long(keyword, token_line);
                        add_next_index_zval(return_value, keyword);
                } else {