diff options
Diffstat (limited to 'Zend/zend_language_scanner.l')
-rw-r--r-- | Zend/zend_language_scanner.l | 85 |
1 files changed, 50 insertions, 35 deletions
diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index cc54557b3b..d44ba20e1b 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -178,22 +178,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) @@ -208,6 +209,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); @@ -234,6 +238,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; @@ -250,12 +258,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) @@ -1035,6 +1037,10 @@ NEWLINE ("\r"|"\n"|"\r\n") return T_RETURN; } +<ST_IN_SCRIPTING>"yield" { + return T_YIELD; +} + <ST_IN_SCRIPTING>"try" { return T_TRY; } @@ -1043,6 +1049,10 @@ NEWLINE ("\r"|"\n"|"\r\n") return T_CATCH; } +<ST_IN_SCRIPTING>"finally" { + return T_FINALLY; +} + <ST_IN_SCRIPTING>"throw" { return T_THROW; } @@ -1463,7 +1473,8 @@ NEWLINE ("\r"|"\n"|"\r\n") } -<ST_LOOKING_FOR_VARNAME>{LABEL} { +<ST_LOOKING_FOR_VARNAME>{LABEL}[[}] { + yyless(yyleng - 1); zend_copy_value(zendlval, yytext, yyleng); zendlval->type = IS_STRING; yy_pop_state(TSRMLS_C); @@ -2106,38 +2117,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++; @@ -2148,6 +2156,8 @@ inline_html: } } + zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) heredoc_label); + return T_START_HEREDOC; } @@ -2159,13 +2169,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; } @@ -2285,6 +2296,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; } @@ -2300,8 +2313,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++; @@ -2357,6 +2370,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; } @@ -2372,8 +2387,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++; |