mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
. Added support for using static HEREDOCs to initialize static variables and class members or constants. (Matt)
. Improved syntax highlighting and consistency for variables in double-quoted strings and literal text in HEREDOCs and backticks. (Matt) . Optimized interpolated strings to use one less opcode. (Matt)
This commit is contained in:
parent
2d49dc63e6
commit
ef5f3cfdf2
@ -19,6 +19,6 @@ highlight_string($code);
|
||||
?>
|
||||
--EXPECT--
|
||||
<code><span style="color: #000000">
|
||||
<br /><span style="color: #0000BB"><?php<br /> $x </span><span style="color: #007700">= <<<EOT<br /></span><span style="color: #0000BB">some string <br /></span><span style="color: #007700">EOT<br /> </span><span style="color: #0000BB">$y </span><span style="color: #007700">= </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?></span>
|
||||
<br /><span style="color: #0000BB"><?php<br /> $x </span><span style="color: #007700">= <<<EOT<br /></span><span style="color: #DD0000">some string <br /></span><span style="color: #007700">EOT<br /> </span><span style="color: #0000BB">$y </span><span style="color: #007700">= </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?></span>
|
||||
</span>
|
||||
</code>
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Heredocs can NOT be used as static scalars.
|
||||
STATIC heredocs CAN be used as static scalars.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
@ -7,14 +7,14 @@ require_once 'nowdoc.inc';
|
||||
|
||||
class e {
|
||||
|
||||
const E = <<<THISMUSTERROR
|
||||
If you see this, something's wrong.
|
||||
THISMUSTERROR;
|
||||
const E = <<<THISMUSTNOTERROR
|
||||
If you DON'T see this, something's wrong.
|
||||
THISMUSTNOTERROR;
|
||||
|
||||
};
|
||||
|
||||
print e::E . "\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parse error: parse error in %sheredoc_011.php on line %d
|
||||
--EXPECT--
|
||||
If you DON'T see this, something's wrong.
|
||||
|
@ -21,6 +21,6 @@ highlight_string($code);
|
||||
?>
|
||||
--EXPECT--
|
||||
<code><span style="color: #000000">
|
||||
<span style="color: #0000BB"><?php<br /> $x </span><span style="color: #007700">= <<<'EOT'<br /></span><span style="color: #0000BB">some string <br /></span><span style="color: #007700">EOT<br /> </span><span style="color: #0000BB">$y </span><span style="color: #007700">= </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?></span>
|
||||
<span style="color: #0000BB"><?php<br /> $x </span><span style="color: #007700">= <<<'EOT'<br /></span><span style="color: #DD0000">some string <br /></span><span style="color: #007700">EOT<br /> </span><span style="color: #0000BB">$y </span><span style="color: #007700">= </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?></span>
|
||||
</span>
|
||||
</code>
|
||||
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Highliting empty nowdoc
|
||||
Highlighting empty nowdoc
|
||||
--INI--
|
||||
highlight.string = #DD0000
|
||||
highlight.comment = #FF8000
|
||||
@ -20,6 +20,6 @@ highlight_string($code);
|
||||
?>
|
||||
--EXPECT--
|
||||
<code><span style="color: #000000">
|
||||
<span style="color: #0000BB"><?php<br /> $x </span><span style="color: #007700">= <<<'EOT'<br /></span><span style="color: #0000BB"></span><span style="color: #007700">EOT<br /> </span><span style="color: #0000BB">$y </span><span style="color: #007700">= </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?></span>
|
||||
<span style="color: #0000BB"><?php<br /> $x </span><span style="color: #007700">= <<<'EOT'<br />EOT<br /> </span><span style="color: #0000BB">$y </span><span style="color: #007700">= </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?></span>
|
||||
</span>
|
||||
</code>
|
||||
|
@ -1078,20 +1078,6 @@ void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_do_init_string(znode *result TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
|
||||
opline->opcode = ZEND_INIT_STRING;
|
||||
opline->result.op_type = IS_TMP_VAR;
|
||||
opline->result.u.var = get_temporary_variable(CG(active_op_array));
|
||||
opline->extended_value = CG(literal_type);
|
||||
*result = opline->result;
|
||||
SET_UNUSED(opline->op1);
|
||||
SET_UNUSED(opline->op2);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_do_add_string(znode *result, znode *op1, znode *op2 TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_op *opline;
|
||||
@ -1111,45 +1097,35 @@ void zend_do_add_string(znode *result, znode *op1, znode *op2 TSRMLS_DC) /* {{{
|
||||
efree(Z_UNIVAL(op2->u.constant).v);
|
||||
return;
|
||||
}
|
||||
opline->op1 = *op1;
|
||||
|
||||
if (op1) {
|
||||
opline->op1 = *op1;
|
||||
opline->result = *op1;
|
||||
} else {
|
||||
SET_UNUSED(opline->op1);
|
||||
opline->result.op_type = IS_TMP_VAR;
|
||||
opline->result.u.var = get_temporary_variable(CG(active_op_array));
|
||||
}
|
||||
opline->op2 = *op2;
|
||||
opline->op2.op_type = IS_CONST;
|
||||
opline->result = opline->op1;
|
||||
opline->extended_value = CG(literal_type);
|
||||
*result = opline->result;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_do_add_variable(znode *result, znode *op1, znode *op2 TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_op *opline;
|
||||
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
|
||||
if (op1->op_type == IS_CONST) {
|
||||
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
opline->opcode = ZEND_INIT_STRING;
|
||||
opline->opcode = ZEND_ADD_VAR;
|
||||
|
||||
if (op1) {
|
||||
opline->op1 = *op1;
|
||||
opline->result = *op1;
|
||||
} else {
|
||||
SET_UNUSED(opline->op1);
|
||||
opline->result.op_type = IS_TMP_VAR;
|
||||
opline->result.u.var = get_temporary_variable(CG(active_op_array));
|
||||
*result = opline->result;
|
||||
SET_UNUSED(opline->op1);
|
||||
SET_UNUSED(opline->op2);
|
||||
|
||||
if (Z_STRLEN(op1->u.constant)>0) {
|
||||
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
opline->opcode = ZEND_ADD_STRING;
|
||||
opline->result = *result;
|
||||
opline->op1 = *result;
|
||||
opline->op2 = *op1;
|
||||
opline->result = opline->op1;
|
||||
} else {
|
||||
zval_dtor(&op1->u.constant);
|
||||
}
|
||||
} else {
|
||||
*result = *op1;
|
||||
}
|
||||
|
||||
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
opline->opcode = ZEND_ADD_VAR;
|
||||
opline->result = *result;
|
||||
opline->op1 = *result;
|
||||
opline->op2 = *op2;
|
||||
opline->extended_value = CG(literal_type);
|
||||
*result = opline->result;
|
||||
@ -4168,6 +4144,7 @@ void zend_do_shell_exec(znode *result, znode *cmd TSRMLS_DC) /* {{{ */
|
||||
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
|
||||
switch (cmd->op_type) {
|
||||
case IS_CONST:
|
||||
case IS_TMP_VAR:
|
||||
opline->opcode = ZEND_SEND_VAL;
|
||||
break;
|
||||
@ -5153,7 +5130,6 @@ again:
|
||||
retval = T_ECHO;
|
||||
break;
|
||||
case T_END_HEREDOC:
|
||||
case T_END_NOWDOC:
|
||||
efree(Z_STRVAL(zendlval->u.constant));
|
||||
break;
|
||||
}
|
||||
|
@ -422,7 +422,6 @@ void zend_check_writable_variable(znode *variable);
|
||||
|
||||
void zend_do_free(znode *op1 TSRMLS_DC);
|
||||
|
||||
void zend_do_init_string(znode *result TSRMLS_DC);
|
||||
void zend_do_add_string(znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
||||
void zend_do_add_variable(znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
||||
|
||||
|
@ -77,7 +77,6 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
int token_type;
|
||||
char *last_color = syntax_highlighter_ini->highlight_html;
|
||||
char *next_color;
|
||||
int in_string=0;
|
||||
|
||||
CG(literal_type) = IS_STRING;
|
||||
zend_printf("<code>");
|
||||
@ -100,22 +99,18 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
case T_CLOSE_TAG:
|
||||
next_color = syntax_highlighter_ini->highlight_default;
|
||||
break;
|
||||
case '"':
|
||||
case T_ENCAPSED_AND_WHITESPACE:
|
||||
case T_CONSTANT_ENCAPSED_STRING:
|
||||
next_color = syntax_highlighter_ini->highlight_string;
|
||||
break;
|
||||
case '"':
|
||||
next_color = syntax_highlighter_ini->highlight_string;
|
||||
in_string = !in_string;
|
||||
break;
|
||||
case T_WHITESPACE:
|
||||
zend_html_puts(LANG_SCNG(yy_text), LANG_SCNG(yy_leng) TSRMLS_CC); /* no color needed */
|
||||
Z_TYPE(token) = 0;
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
if (in_string) {
|
||||
next_color = syntax_highlighter_ini->highlight_string;
|
||||
} else if (Z_TYPE(token) == 0) {
|
||||
if (Z_TYPE(token) == 0) {
|
||||
next_color = syntax_highlighter_ini->highlight_keyword;
|
||||
} else {
|
||||
next_color = syntax_highlighter_ini->highlight_default;
|
||||
@ -134,7 +129,6 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
}
|
||||
switch (token_type) {
|
||||
case T_END_HEREDOC:
|
||||
case T_END_NOWDOC:
|
||||
zend_html_puts(Z_STRVAL(token), Z_STRLEN(token) TSRMLS_CC);
|
||||
break;
|
||||
default:
|
||||
@ -156,7 +150,7 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
efree(Z_UNIVAL(token).v);
|
||||
break;
|
||||
}
|
||||
} else if (token_type == T_END_HEREDOC || token_type == T_END_NOWDOC) {
|
||||
} else if (token_type == T_END_HEREDOC) {
|
||||
efree(Z_UNIVAL(token).v);
|
||||
}
|
||||
Z_TYPE(token) = 0;
|
||||
@ -204,11 +198,7 @@ ZEND_API void zend_strip(TSRMLS_D) /* {{{ */
|
||||
Z_TYPE(token) = 0;
|
||||
continue;
|
||||
|
||||
case EOF:
|
||||
return;
|
||||
|
||||
case T_END_HEREDOC:
|
||||
case T_END_NOWDOC:
|
||||
zend_write(LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
|
||||
efree(Z_STRVAL(token));
|
||||
/* read the following character, either newline or ; */
|
||||
|
@ -23,7 +23,7 @@
|
||||
/*
|
||||
* LALR shift/reduce conflicts and how they are resolved:
|
||||
*
|
||||
* - 2 shift/reduce conflicts due to the dangeling elseif/else ambiguity. Solved by shift.
|
||||
* - 2 shift/reduce conflicts due to the dangling elseif/else ambiguity. Solved by shift.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -149,8 +149,6 @@
|
||||
%token T_NAMESPACE
|
||||
%token T_NS_C
|
||||
%token T_DIR
|
||||
%token T_START_NOWDOC
|
||||
%token T_END_NOWDOC
|
||||
|
||||
%% /* Rules */
|
||||
|
||||
@ -645,7 +643,7 @@ expr_without_variable:
|
||||
| '@' { zend_do_begin_silence(&$1 TSRMLS_CC); } expr { zend_do_end_silence(&$1 TSRMLS_CC); $$ = $3; }
|
||||
| scalar { $$ = $1; }
|
||||
| T_ARRAY '(' array_pair_list ')' { $$ = $3; }
|
||||
| '`' { CG(literal_type) = UG(unicode)?IS_UNICODE:IS_STRING; } encaps_list '`' { zend_do_shell_exec(&$$, &$3 TSRMLS_CC); }
|
||||
| '`' { CG(literal_type) = UG(unicode)?IS_UNICODE:IS_STRING; } backticks_expr '`' { zend_do_shell_exec(&$$, &$3 TSRMLS_CC); }
|
||||
| T_PRINT expr { zend_do_print(&$$, &$2 TSRMLS_CC); }
|
||||
| function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type, 0 TSRMLS_CC); }
|
||||
parameter_list ')' lexical_vars '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $4; }
|
||||
@ -739,6 +737,12 @@ exit_expr:
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
backticks_expr:
|
||||
/* empty */ { ZVAL_EMPTY_TEXT(&$$.u.constant); INIT_PZVAL(&$$.u.constant); $$.op_type = IS_CONST; }
|
||||
| T_ENCAPSED_AND_WHITESPACE { $$ = $1; }
|
||||
| encaps_list { $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
ctor_arguments:
|
||||
/* empty */ { Z_LVAL($$.u.constant)=0; }
|
||||
@ -757,7 +761,13 @@ common_scalar:
|
||||
| T_METHOD_C { $$ = $1; }
|
||||
| T_FUNC_C { $$ = $1; }
|
||||
| T_NS_C { $$ = $1; }
|
||||
| T_START_NOWDOC T_ENCAPSED_AND_WHITESPACE T_END_NOWDOC { $$ = $2; }
|
||||
| start_heredoc T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $$ = $2; }
|
||||
| start_heredoc T_END_HEREDOC { if (CG(literal_type) == IS_UNICODE) { ZVAL_EMPTY_UNICODE(&$$.u.constant); } else { ZVAL_EMPTY_STRING(&$$.u.constant); } INIT_PZVAL(&$$.u.constant); $$.op_type = IS_CONST; }
|
||||
;
|
||||
|
||||
start_heredoc:
|
||||
T_START_HEREDOC { CG(literal_type) = UG(unicode)?IS_UNICODE:IS_STRING; }
|
||||
| T_BINARY_HEREDOC { CG(literal_type) = IS_STRING; }
|
||||
;
|
||||
|
||||
|
||||
@ -782,9 +792,8 @@ scalar:
|
||||
| class_constant { $$ = $1; }
|
||||
| common_scalar { $$ = $1; }
|
||||
| '"' { CG(literal_type) = UG(unicode)?IS_UNICODE:IS_STRING; } encaps_list '"' { $$ = $3; }
|
||||
| T_START_HEREDOC { CG(literal_type) = UG(unicode)?IS_UNICODE:IS_STRING; } encaps_list T_END_HEREDOC { $$ = $3; }
|
||||
| T_BINARY_DOUBLE { CG(literal_type) = IS_STRING; } encaps_list '"' { $$ = $3; }
|
||||
| T_BINARY_HEREDOC { CG(literal_type) = IS_STRING; } encaps_list T_END_HEREDOC { $$ = $3; }
|
||||
| start_heredoc encaps_list T_END_HEREDOC { $$ = $2; }
|
||||
;
|
||||
|
||||
|
||||
@ -947,8 +956,8 @@ non_empty_array_pair_list:
|
||||
encaps_list:
|
||||
encaps_list encaps_var { zend_do_end_variable_parse(&$2, BP_VAR_R, 0 TSRMLS_CC); zend_do_add_variable(&$$, &$1, &$2 TSRMLS_CC); }
|
||||
| encaps_list T_ENCAPSED_AND_WHITESPACE { zend_do_add_string(&$$, &$1, &$2 TSRMLS_CC); }
|
||||
| /* empty */ { zend_do_init_string(&$$ TSRMLS_CC); }
|
||||
|
||||
| encaps_var { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_add_variable(&$$, NULL, &$1 TSRMLS_CC); }
|
||||
| T_ENCAPSED_AND_WHITESPACE encaps_var { zend_do_add_string(&$$, NULL, &$1 TSRMLS_CC); zend_do_end_variable_parse(&$2, BP_VAR_R, 0 TSRMLS_CC); zend_do_add_variable(&$$, &$$, &$2 TSRMLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1420,7 +1420,7 @@ DOUBLE_QUOTES_CHARS ("{"*([^$"\\{]|("\\"{ANY_CHAR}))|{DOUBLE_QUOTES_LITERAL_DOLL
|
||||
BACKQUOTE_CHARS ("{"*([^$`\\{]|("\\"{ANY_CHAR}))|{BACKQUOTE_LITERAL_DOLLAR})
|
||||
HEREDOC_CHARS ("{"*([^$\n\r\\{]|("\\"[^\n\r]))|{HEREDOC_LITERAL_DOLLAR}|({HEREDOC_NEWLINE}+({HEREDOC_NON_LABEL}|{HEREDOC_LABEL_NO_NEWLINE})))
|
||||
|
||||
NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_\x7f-\xff;\n\r][^\n\r]*)|({LABEL}[;][^\n\r]+)))
|
||||
NOWDOC_CHARS ([^\n\r]|{NEWLINE}+([^a-zA-Z_\x7f-\xff\n\r]|({LABEL}([^a-zA-Z0-9_\x7f-\xff;\n\r]|(";"[^\n\r])))))
|
||||
|
||||
/* compute yyleng before each rule */
|
||||
<!*> := yyleng = YYCURSOR - SCNG(yy_text);
|
||||
@ -2423,45 +2423,48 @@ inline_char_handler:
|
||||
return T_BINARY_DOUBLE;
|
||||
}
|
||||
|
||||
<ST_IN_SCRIPTING>b"<<<"{TABS_AND_SPACES}({LABEL}|["]{LABEL}["]){NEWLINE} {
|
||||
<ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}({LABEL}|([']{LABEL}['])|(["]{LABEL}["])){NEWLINE} {
|
||||
char *s;
|
||||
int bprefix = (yytext[0] != '<') ? 1 : 0;
|
||||
|
||||
CG(zend_lineno)++;
|
||||
CG(heredoc_len) = yyleng-4-1-(yytext[yyleng-2]=='\r'?1:0);
|
||||
s = yytext+4;
|
||||
CG(heredoc_len) = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0);
|
||||
s = yytext+bprefix+3;
|
||||
while ((*s == ' ') || (*s == '\t')) {
|
||||
s++;
|
||||
CG(heredoc_len)--;
|
||||
}
|
||||
|
||||
if (*s == '"') {
|
||||
if (*s == '\'') {
|
||||
s++;
|
||||
CG(heredoc_len) -= 2;
|
||||
|
||||
BEGIN(ST_NOWDOC);
|
||||
} else {
|
||||
if (*s == '"') {
|
||||
s++;
|
||||
CG(heredoc_len) -= 2;
|
||||
}
|
||||
|
||||
BEGIN(ST_HEREDOC);
|
||||
}
|
||||
|
||||
CG(heredoc) = estrndup(s, CG(heredoc_len));
|
||||
BEGIN(ST_START_HEREDOC);
|
||||
return T_BINARY_HEREDOC;
|
||||
}
|
||||
|
||||
/* Check for ending label on the next line */
|
||||
if (CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, CG(heredoc_len))) {
|
||||
char *end = YYCURSOR + CG(heredoc_len);
|
||||
|
||||
<ST_IN_SCRIPTING>"<<<"{TABS_AND_SPACES}({LABEL}|["]{LABEL}["]){NEWLINE} {
|
||||
char *s;
|
||||
if (*end == ';') {
|
||||
end++;
|
||||
}
|
||||
|
||||
CG(zend_lineno)++;
|
||||
CG(heredoc_len) = yyleng-3-1-(yytext[yyleng-2]=='\r'?1:0);
|
||||
s = yytext+3;
|
||||
while ((*s == ' ') || (*s == '\t')) {
|
||||
s++;
|
||||
CG(heredoc_len)--;
|
||||
if (*end == '\n' || *end == '\r') {
|
||||
BEGIN(ST_END_HEREDOC);
|
||||
}
|
||||
}
|
||||
|
||||
if (*s == '"') {
|
||||
s++;
|
||||
CG(heredoc_len) -= 2;
|
||||
}
|
||||
CG(heredoc) = estrndup(s, CG(heredoc_len));
|
||||
BEGIN(ST_START_HEREDOC);
|
||||
return T_START_HEREDOC;
|
||||
return bprefix ? T_BINARY_HEREDOC : T_START_HEREDOC;
|
||||
}
|
||||
|
||||
|
||||
@ -2471,34 +2474,6 @@ inline_char_handler:
|
||||
}
|
||||
|
||||
|
||||
<ST_START_HEREDOC>{ANY_CHAR} {
|
||||
yyless(0);
|
||||
BEGIN(ST_HEREDOC);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
<ST_START_HEREDOC>{LABEL}";"?[\n\r] {
|
||||
int label_len = yyleng - 1;
|
||||
|
||||
if (yytext[label_len-1]==';') {
|
||||
label_len--;
|
||||
}
|
||||
|
||||
yyless(label_len);
|
||||
|
||||
if (label_len==CG(heredoc_len) && !memcmp(yytext, CG(heredoc), label_len)) {
|
||||
Z_STRVAL_P(zendlval) = CG(heredoc);
|
||||
Z_STRLEN_P(zendlval) = label_len;
|
||||
CG(heredoc)=NULL;
|
||||
CG(heredoc_len)=0;
|
||||
BEGIN(ST_IN_SCRIPTING);
|
||||
return T_END_HEREDOC;
|
||||
} else {
|
||||
BEGIN(ST_HEREDOC);
|
||||
yymore();
|
||||
}
|
||||
}
|
||||
|
||||
/* Match everything up to and including a possible ending label, so if the label
|
||||
* doesn't match, it's kept with the rest of the string
|
||||
*
|
||||
@ -2526,12 +2501,9 @@ inline_char_handler:
|
||||
len--; /* Windows newline */
|
||||
}
|
||||
|
||||
/* Go back before last label char, to match in ST_END_HEREDOC state */
|
||||
yyless(yyleng - 2);
|
||||
|
||||
/* Subtract the remaining label length. yyleng must include newline
|
||||
* before label, for zend_highlight/strip, tokenizer, etc. */
|
||||
yyleng -= CG(heredoc_len) - 1;
|
||||
/* Go back before label, to match in ST_END_HEREDOC state. yytext will include
|
||||
* newline before label, for zend_highlight/strip, tokenizer, etc. */
|
||||
yyless(yyleng - CG(heredoc_len) - 1); /* 1 for newline after label */
|
||||
|
||||
CG(increment_lineno) = 1; /* For newline before label */
|
||||
BEGIN(ST_END_HEREDOC);
|
||||
@ -2551,8 +2523,11 @@ inline_char_handler:
|
||||
}
|
||||
|
||||
<ST_END_HEREDOC>{ANY_CHAR} {
|
||||
SCNG(yy_text) = Z_STRVAL_P(zendlval) = CG(heredoc);
|
||||
SCNG(yy_leng) = Z_STRLEN_P(zendlval) = CG(heredoc_len);
|
||||
YYCURSOR += CG(heredoc_len) - 1;
|
||||
yyleng = CG(heredoc_len);
|
||||
|
||||
Z_STRVAL_P(zendlval) = CG(heredoc);
|
||||
Z_STRLEN_P(zendlval) = CG(heredoc_len);
|
||||
CG(heredoc) = NULL;
|
||||
CG(heredoc_len) = 0;
|
||||
BEGIN(ST_IN_SCRIPTING);
|
||||
@ -2644,58 +2619,7 @@ inline_char_handler:
|
||||
}
|
||||
|
||||
|
||||
/* BEGIN nowdoc */
|
||||
|
||||
<ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}[']{LABEL}[']{NEWLINE} {
|
||||
int bprefix = (yytext[0] != '<') ? 1 : 0;
|
||||
char *s;
|
||||
CG(zend_lineno)++;
|
||||
/* 3 is <<<, 2 is quotes, 1 is newline */
|
||||
CG(heredoc_len) = yyleng-bprefix-3-2-1-(yytext[yyleng-2]=='\r'?1:0);
|
||||
s = yytext+bprefix+3;
|
||||
while ((*s == ' ') || (*s == '\t')) {
|
||||
s++;
|
||||
CG(heredoc_len)--;
|
||||
}
|
||||
s++; /* first quote */
|
||||
CG(heredoc) = estrndup(s, CG(heredoc_len));
|
||||
|
||||
CG(literal_type) = bprefix?IS_STRING:ZEND_STR_TYPE;
|
||||
BEGIN(ST_START_NOWDOC);
|
||||
return T_START_NOWDOC;
|
||||
}
|
||||
|
||||
<ST_START_NOWDOC>{ANY_CHAR} {
|
||||
yyless(0);
|
||||
BEGIN(ST_NOWDOC);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
<ST_START_NOWDOC>{LABEL}";"?[\r\n] {
|
||||
int label_len = yyleng - 1;
|
||||
|
||||
if (yytext[label_len-1]==';') {
|
||||
label_len--;
|
||||
}
|
||||
|
||||
if (label_len==CG(heredoc_len) && !memcmp(yytext, CG(heredoc), label_len)) {
|
||||
yyless(label_len-1);
|
||||
yyleng = 0;
|
||||
BEGIN(ST_END_NOWDOC);
|
||||
if (CG(literal_type) == IS_UNICODE) {
|
||||
ZVAL_EMPTY_UNICODE(zendlval);
|
||||
} else {
|
||||
ZVAL_EMPTY_STRING(zendlval);
|
||||
}
|
||||
return T_ENCAPSED_AND_WHITESPACE;
|
||||
} else {
|
||||
BEGIN(ST_NOWDOC);
|
||||
yyless(label_len);
|
||||
yymore();
|
||||
}
|
||||
}
|
||||
|
||||
<ST_NOWDOC>{NOWDOC_CHARS}*{NEWLINE}+{LABEL}";"?[\n\r] {
|
||||
<ST_NOWDOC>({NOWDOC_CHARS}+{NEWLINE}+|{NEWLINE}+){LABEL}";"?[\n\r] {
|
||||
char *end = yytext + yyleng - 1;
|
||||
|
||||
if (end[-1] == ';') {
|
||||
@ -2716,20 +2640,17 @@ inline_char_handler:
|
||||
len--; /* Windows newline */
|
||||
}
|
||||
|
||||
/* Go back before last label char, to match in ST_END_NOWDOC state */
|
||||
yyless(yyleng - 2);
|
||||
|
||||
/* Subtract the remaining label length. yyleng must include newline
|
||||
* before label, for zend_highlight/strip, tokenizer, etc. */
|
||||
yyleng -= CG(heredoc_len) - 1;
|
||||
/* Go back before label, to match in ST_END_HEREDOC state. yytext will include
|
||||
* newline before label, for zend_highlight/strip, tokenizer, etc. */
|
||||
yyless(yyleng - CG(heredoc_len) - 1); /* 1 for newline after label */
|
||||
|
||||
CG(increment_lineno) = 1; /* For newline before label */
|
||||
BEGIN(ST_END_NOWDOC);
|
||||
BEGIN(ST_END_HEREDOC);
|
||||
|
||||
HANDLE_NEWLINES(yytext, len);
|
||||
if (!zend_copy_scanner_string(zendlval, yytext, len, CG(literal_type), SCNG(output_conv) TSRMLS_CC)) {
|
||||
return 0;
|
||||
}
|
||||
HANDLE_NEWLINES(yytext, len);
|
||||
return T_ENCAPSED_AND_WHITESPACE;
|
||||
} else {
|
||||
/* Go back to end of label, so the next match works correctly in case of
|
||||
@ -2739,16 +2660,6 @@ inline_char_handler:
|
||||
}
|
||||
}
|
||||
|
||||
<ST_END_NOWDOC>{ANY_CHAR} {
|
||||
SCNG(yy_text) = Z_STRVAL_P(zendlval) = CG(heredoc);
|
||||
SCNG(yy_leng) = Z_STRLEN_P(zendlval) = CG(heredoc_len);
|
||||
CG(heredoc) = NULL;
|
||||
CG(heredoc_len) = 0;
|
||||
BEGIN(ST_IN_SCRIPTING);
|
||||
return T_END_NOWDOC;
|
||||
}
|
||||
|
||||
/* END nowdoc */
|
||||
|
||||
<ST_DOUBLE_QUOTES>["] {
|
||||
BEGIN(ST_IN_SCRIPTING);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Generated by re2c 0.13.6.dev on Tue Jul 8 16:24:44 2008 */
|
||||
/* Generated by re2c 0.13.5 on Sat Jul 26 19:05:04 2008 */
|
||||
#line 3 "Zend/zend_language_scanner_defs.h"
|
||||
|
||||
enum YYCONDTYPE {
|
||||
@ -13,9 +13,6 @@ enum YYCONDTYPE {
|
||||
yycST_ONE_LINE_COMMENT,
|
||||
yycST_COMMENT,
|
||||
yycST_DOC_COMMENT,
|
||||
yycST_START_HEREDOC,
|
||||
yycST_END_HEREDOC,
|
||||
yycST_START_NOWDOC,
|
||||
yycST_NOWDOC,
|
||||
yycST_END_NOWDOC,
|
||||
};
|
||||
|
@ -1824,38 +1824,64 @@ ZEND_VM_HANDLER(53, ZEND_INIT_STRING, ANY, ANY)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(54, ZEND_ADD_CHAR, TMP, CONST)
|
||||
ZEND_VM_HANDLER(54, ZEND_ADD_CHAR, TMP|UNUSED, CONST)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1;
|
||||
zval *str = &EX_T(opline->result.u.var).tmp_var;
|
||||
|
||||
if (OP1_TYPE == IS_UNUSED) {
|
||||
/* Initialize for erealloc in add_char_to_string */
|
||||
Z_UNIVAL_P(str).v = NULL;
|
||||
Z_UNILEN_P(str) = 0;
|
||||
Z_TYPE_P(str) = opline->extended_value;
|
||||
|
||||
INIT_PZVAL(str);
|
||||
}
|
||||
|
||||
add_char_to_string(str, str, &opline->op2.u.constant);
|
||||
|
||||
add_char_to_string(&EX_T(opline->result.u.var).tmp_var,
|
||||
GET_OP1_ZVAL_PTR(BP_VAR_NA),
|
||||
&opline->op2.u.constant);
|
||||
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(55, ZEND_ADD_STRING, TMP, CONST)
|
||||
ZEND_VM_HANDLER(55, ZEND_ADD_STRING, TMP|UNUSED, CONST)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1;
|
||||
zval *str = &EX_T(opline->result.u.var).tmp_var;
|
||||
|
||||
if (OP1_TYPE == IS_UNUSED) {
|
||||
/* Initialize for erealloc in add_string_to_string */
|
||||
Z_UNIVAL_P(str).v = NULL;
|
||||
Z_UNILEN_P(str) = 0;
|
||||
Z_TYPE_P(str) = opline->extended_value;
|
||||
|
||||
INIT_PZVAL(str);
|
||||
}
|
||||
|
||||
add_string_to_string(str, str, &opline->op2.u.constant);
|
||||
|
||||
add_string_to_string(&EX_T(opline->result.u.var).tmp_var,
|
||||
GET_OP1_ZVAL_PTR(BP_VAR_NA),
|
||||
&opline->op2.u.constant);
|
||||
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP, TMP|VAR|CV)
|
||||
ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP|UNUSED, TMP|VAR|CV)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1, free_op2;
|
||||
zend_free_op free_op2;
|
||||
zval *str = &EX_T(opline->result.u.var).tmp_var;
|
||||
zval *var = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
zval var_copy;
|
||||
int use_copy = 0;
|
||||
|
||||
if (OP1_TYPE == IS_UNUSED) {
|
||||
/* Initialize for erealloc in add_string_to_string */
|
||||
Z_UNIVAL_P(str).v = NULL;
|
||||
Z_UNILEN_P(str) = 0;
|
||||
Z_TYPE_P(str) = opline->extended_value;
|
||||
|
||||
INIT_PZVAL(str);
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(var) != opline->extended_value) {
|
||||
if (opline->extended_value == IS_UNICODE) {
|
||||
zend_make_unicode_zval(var, &var_copy, &use_copy);
|
||||
@ -1867,8 +1893,8 @@ ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP, TMP|VAR|CV)
|
||||
var = &var_copy;
|
||||
}
|
||||
}
|
||||
add_string_to_string(&EX_T(opline->result.u.var).tmp_var,
|
||||
GET_OP1_ZVAL_PTR(BP_VAR_NA), var);
|
||||
add_string_to_string(str, str, var);
|
||||
|
||||
if (use_copy) {
|
||||
zval_dtor(var);
|
||||
}
|
||||
|
@ -6110,11 +6110,19 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC
|
||||
static int ZEND_FASTCALL ZEND_ADD_CHAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1;
|
||||
zval *str = &EX_T(opline->result.u.var).tmp_var;
|
||||
|
||||
if (IS_TMP_VAR == IS_UNUSED) {
|
||||
/* Initialize for erealloc in add_char_to_string */
|
||||
Z_UNIVAL_P(str).v = NULL;
|
||||
Z_UNILEN_P(str) = 0;
|
||||
Z_TYPE_P(str) = opline->extended_value;
|
||||
|
||||
INIT_PZVAL(str);
|
||||
}
|
||||
|
||||
add_char_to_string(str, str, &opline->op2.u.constant);
|
||||
|
||||
add_char_to_string(&EX_T(opline->result.u.var).tmp_var,
|
||||
_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
|
||||
&opline->op2.u.constant);
|
||||
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
@ -6122,11 +6130,19 @@ static int ZEND_FASTCALL ZEND_ADD_CHAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDL
|
||||
static int ZEND_FASTCALL ZEND_ADD_STRING_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1;
|
||||
zval *str = &EX_T(opline->result.u.var).tmp_var;
|
||||
|
||||
if (IS_TMP_VAR == IS_UNUSED) {
|
||||
/* Initialize for erealloc in add_string_to_string */
|
||||
Z_UNIVAL_P(str).v = NULL;
|
||||
Z_UNILEN_P(str) = 0;
|
||||
Z_TYPE_P(str) = opline->extended_value;
|
||||
|
||||
INIT_PZVAL(str);
|
||||
}
|
||||
|
||||
add_string_to_string(str, str, &opline->op2.u.constant);
|
||||
|
||||
add_string_to_string(&EX_T(opline->result.u.var).tmp_var,
|
||||
_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
|
||||
&opline->op2.u.constant);
|
||||
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
@ -6560,11 +6576,21 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER
|
||||
static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1, free_op2;
|
||||
zend_free_op free_op2;
|
||||
zval *str = &EX_T(opline->result.u.var).tmp_var;
|
||||
zval *var = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
|
||||
zval var_copy;
|
||||
int use_copy = 0;
|
||||
|
||||
if (IS_TMP_VAR == IS_UNUSED) {
|
||||
/* Initialize for erealloc in add_string_to_string */
|
||||
Z_UNIVAL_P(str).v = NULL;
|
||||
Z_UNILEN_P(str) = 0;
|
||||
Z_TYPE_P(str) = opline->extended_value;
|
||||
|
||||
INIT_PZVAL(str);
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(var) != opline->extended_value) {
|
||||
if (opline->extended_value == IS_UNICODE) {
|
||||
zend_make_unicode_zval(var, &var_copy, &use_copy);
|
||||
@ -6576,8 +6602,8 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_
|
||||
var = &var_copy;
|
||||
}
|
||||
}
|
||||
add_string_to_string(&EX_T(opline->result.u.var).tmp_var,
|
||||
_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), var);
|
||||
add_string_to_string(str, str, var);
|
||||
|
||||
if (use_copy) {
|
||||
zval_dtor(var);
|
||||
}
|
||||
@ -7023,11 +7049,21 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER
|
||||
static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1, free_op2;
|
||||
zend_free_op free_op2;
|
||||
zval *str = &EX_T(opline->result.u.var).tmp_var;
|
||||
zval *var = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
|
||||
zval var_copy;
|
||||
int use_copy = 0;
|
||||
|
||||
if (IS_TMP_VAR == IS_UNUSED) {
|
||||
/* Initialize for erealloc in add_string_to_string */
|
||||
Z_UNIVAL_P(str).v = NULL;
|
||||
Z_UNILEN_P(str) = 0;
|
||||
Z_TYPE_P(str) = opline->extended_value;
|
||||
|
||||
INIT_PZVAL(str);
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(var) != opline->extended_value) {
|
||||
if (opline->extended_value == IS_UNICODE) {
|
||||
zend_make_unicode_zval(var, &var_copy, &use_copy);
|
||||
@ -7039,8 +7075,8 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_
|
||||
var = &var_copy;
|
||||
}
|
||||
}
|
||||
add_string_to_string(&EX_T(opline->result.u.var).tmp_var,
|
||||
_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), var);
|
||||
add_string_to_string(str, str, var);
|
||||
|
||||
if (use_copy) {
|
||||
zval_dtor(var);
|
||||
}
|
||||
@ -7580,11 +7616,21 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_
|
||||
static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1;
|
||||
|
||||
zval *str = &EX_T(opline->result.u.var).tmp_var;
|
||||
zval *var = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
|
||||
zval var_copy;
|
||||
int use_copy = 0;
|
||||
|
||||
if (IS_TMP_VAR == IS_UNUSED) {
|
||||
/* Initialize for erealloc in add_string_to_string */
|
||||
Z_UNIVAL_P(str).v = NULL;
|
||||
Z_UNILEN_P(str) = 0;
|
||||
Z_TYPE_P(str) = opline->extended_value;
|
||||
|
||||
INIT_PZVAL(str);
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(var) != opline->extended_value) {
|
||||
if (opline->extended_value == IS_UNICODE) {
|
||||
zend_make_unicode_zval(var, &var_copy, &use_copy);
|
||||
@ -7596,8 +7642,8 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_A
|
||||
var = &var_copy;
|
||||
}
|
||||
}
|
||||
add_string_to_string(&EX_T(opline->result.u.var).tmp_var,
|
||||
_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), var);
|
||||
add_string_to_string(str, str, var);
|
||||
|
||||
if (use_copy) {
|
||||
zval_dtor(var);
|
||||
}
|
||||
@ -18313,6 +18359,46 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_ADD_CHAR_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zval *str = &EX_T(opline->result.u.var).tmp_var;
|
||||
|
||||
if (IS_UNUSED == IS_UNUSED) {
|
||||
/* Initialize for erealloc in add_char_to_string */
|
||||
Z_UNIVAL_P(str).v = NULL;
|
||||
Z_UNILEN_P(str) = 0;
|
||||
Z_TYPE_P(str) = opline->extended_value;
|
||||
|
||||
INIT_PZVAL(str);
|
||||
}
|
||||
|
||||
add_char_to_string(str, str, &opline->op2.u.constant);
|
||||
|
||||
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_ADD_STRING_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zval *str = &EX_T(opline->result.u.var).tmp_var;
|
||||
|
||||
if (IS_UNUSED == IS_UNUSED) {
|
||||
/* Initialize for erealloc in add_string_to_string */
|
||||
Z_UNIVAL_P(str).v = NULL;
|
||||
Z_UNILEN_P(str) = 0;
|
||||
Z_TYPE_P(str) = opline->extended_value;
|
||||
|
||||
INIT_PZVAL(str);
|
||||
}
|
||||
|
||||
add_string_to_string(str, str, &opline->op2.u.constant);
|
||||
|
||||
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
@ -19469,6 +19555,51 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HA
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op2;
|
||||
zval *str = &EX_T(opline->result.u.var).tmp_var;
|
||||
zval *var = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
|
||||
zval var_copy;
|
||||
int use_copy = 0;
|
||||
|
||||
if (IS_UNUSED == IS_UNUSED) {
|
||||
/* Initialize for erealloc in add_string_to_string */
|
||||
Z_UNIVAL_P(str).v = NULL;
|
||||
Z_UNILEN_P(str) = 0;
|
||||
Z_TYPE_P(str) = opline->extended_value;
|
||||
|
||||
INIT_PZVAL(str);
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(var) != opline->extended_value) {
|
||||
if (opline->extended_value == IS_UNICODE) {
|
||||
zend_make_unicode_zval(var, &var_copy, &use_copy);
|
||||
} else {
|
||||
zend_make_string_zval(var, &var_copy, &use_copy);
|
||||
}
|
||||
|
||||
if (use_copy) {
|
||||
var = &var_copy;
|
||||
}
|
||||
}
|
||||
add_string_to_string(str, str, var);
|
||||
|
||||
if (use_copy) {
|
||||
zval_dtor(var);
|
||||
}
|
||||
/* original comment, possibly problematic:
|
||||
* FREE_OP is missing intentionally here - we're always working on the same temporary variable
|
||||
* (Zeev): I don't think it's problematic, we only use variables
|
||||
* which aren't affected by FREE_OP(Ts, )'s anyway, unless they're
|
||||
* string offsets or overloaded objects
|
||||
*/
|
||||
zval_dtor(free_op2.var);
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
@ -20554,6 +20685,51 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HA
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op2;
|
||||
zval *str = &EX_T(opline->result.u.var).tmp_var;
|
||||
zval *var = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
|
||||
zval var_copy;
|
||||
int use_copy = 0;
|
||||
|
||||
if (IS_UNUSED == IS_UNUSED) {
|
||||
/* Initialize for erealloc in add_string_to_string */
|
||||
Z_UNIVAL_P(str).v = NULL;
|
||||
Z_UNILEN_P(str) = 0;
|
||||
Z_TYPE_P(str) = opline->extended_value;
|
||||
|
||||
INIT_PZVAL(str);
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(var) != opline->extended_value) {
|
||||
if (opline->extended_value == IS_UNICODE) {
|
||||
zend_make_unicode_zval(var, &var_copy, &use_copy);
|
||||
} else {
|
||||
zend_make_string_zval(var, &var_copy, &use_copy);
|
||||
}
|
||||
|
||||
if (use_copy) {
|
||||
var = &var_copy;
|
||||
}
|
||||
}
|
||||
add_string_to_string(str, str, var);
|
||||
|
||||
if (use_copy) {
|
||||
zval_dtor(var);
|
||||
}
|
||||
/* original comment, possibly problematic:
|
||||
* FREE_OP is missing intentionally here - we're always working on the same temporary variable
|
||||
* (Zeev): I don't think it's problematic, we only use variables
|
||||
* which aren't affected by FREE_OP(Ts, )'s anyway, unless they're
|
||||
* string offsets or overloaded objects
|
||||
*/
|
||||
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
@ -21909,6 +22085,50 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAN
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
|
||||
zval *str = &EX_T(opline->result.u.var).tmp_var;
|
||||
zval *var = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
|
||||
zval var_copy;
|
||||
int use_copy = 0;
|
||||
|
||||
if (IS_UNUSED == IS_UNUSED) {
|
||||
/* Initialize for erealloc in add_string_to_string */
|
||||
Z_UNIVAL_P(str).v = NULL;
|
||||
Z_UNILEN_P(str) = 0;
|
||||
Z_TYPE_P(str) = opline->extended_value;
|
||||
|
||||
INIT_PZVAL(str);
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(var) != opline->extended_value) {
|
||||
if (opline->extended_value == IS_UNICODE) {
|
||||
zend_make_unicode_zval(var, &var_copy, &use_copy);
|
||||
} else {
|
||||
zend_make_string_zval(var, &var_copy, &use_copy);
|
||||
}
|
||||
|
||||
if (use_copy) {
|
||||
var = &var_copy;
|
||||
}
|
||||
}
|
||||
add_string_to_string(str, str, var);
|
||||
|
||||
if (use_copy) {
|
||||
zval_dtor(var);
|
||||
}
|
||||
/* original comment, possibly problematic:
|
||||
* FREE_OP is missing intentionally here - we're always working on the same temporary variable
|
||||
* (Zeev): I don't think it's problematic, we only use variables
|
||||
* which aren't affected by FREE_OP(Ts, )'s anyway, unless they're
|
||||
* string offsets or overloaded objects
|
||||
*/
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
@ -32575,7 +32795,7 @@ void zend_init_opcodes_handlers(void)
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_ADD_CHAR_SPEC_UNUSED_CONST_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
@ -32600,7 +32820,7 @@ void zend_init_opcodes_handlers(void)
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_ADD_STRING_SPEC_UNUSED_CONST_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
@ -32626,10 +32846,10 @@ void zend_init_opcodes_handlers(void)
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_ADD_VAR_SPEC_UNUSED_TMP_HANDLER,
|
||||
ZEND_ADD_VAR_SPEC_UNUSED_VAR_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_ADD_VAR_SPEC_UNUSED_CV_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
|
@ -134,7 +134,7 @@ static void tokenize(zval *return_value TSRMLS_DC)
|
||||
MAKE_STD_ZVAL(keyword);
|
||||
array_init(keyword);
|
||||
add_next_index_long(keyword, token_type);
|
||||
if (token_type == T_END_HEREDOC || token_type == T_END_NOWDOC) {
|
||||
if (token_type == T_END_HEREDOC) {
|
||||
if (CG(increment_lineno)) {
|
||||
token_line = ++CG(zend_lineno);
|
||||
CG(increment_lineno) = 0;
|
||||
|
@ -12,6 +12,6 @@ highlight.html=#000000
|
||||
?>
|
||||
--EXPECT--
|
||||
<code><span style="color: #000000">
|
||||
<span style="color: #0000BB"><?php </span><span style="color: #007700">echo </span><span style="color: #DD0000">"foo[] $a \n"</span><span style="color: #007700">; </span><span style="color: #0000BB">?></span>
|
||||
<span style="color: #0000BB"><?php </span><span style="color: #007700">echo </span><span style="color: #DD0000">"foo[] </span><span style="color: #0000BB">$a</span><span style="color: #DD0000"> \n"</span><span style="color: #007700">; </span><span style="color: #0000BB">?></span>
|
||||
</span>
|
||||
</code>
|
||||
|
Loading…
Reference in New Issue
Block a user