Skip to content

Commit 2359608

Browse files
committed
is_literal
1 parent 7bc0dd2 commit 2359608

30 files changed

+1523
-550
lines changed

Zend/zend_compile.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -833,10 +833,12 @@ uint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag) /* {{{ */
833833
/* }}} */
834834

835835
ZEND_API zend_string *zend_create_member_string(zend_string *class_name, zend_string *member_name) {
836-
return zend_string_concat3(
836+
zend_string* string = zend_string_concat3(
837837
ZSTR_VAL(class_name), ZSTR_LEN(class_name),
838838
"::", sizeof("::") - 1,
839839
ZSTR_VAL(member_name), ZSTR_LEN(member_name));
840+
ZSTR_SET_LITERAL_FAST(string);
841+
return string;
840842
}
841843

842844
zend_string *zend_concat_names(char *name1, size_t name1_len, char *name2, size_t name2_len) {
@@ -846,7 +848,11 @@ zend_string *zend_concat_names(char *name1, size_t name1_len, char *name2, size_
846848
zend_string *zend_prefix_with_ns(zend_string *name) {
847849
if (FC(current_namespace)) {
848850
zend_string *ns = FC(current_namespace);
849-
return zend_concat_names(ZSTR_VAL(ns), ZSTR_LEN(ns), ZSTR_VAL(name), ZSTR_LEN(name));
851+
zend_string *prefixed =
852+
zend_concat_names(ZSTR_VAL(ns), ZSTR_LEN(ns), ZSTR_VAL(name), ZSTR_LEN(name));
853+
854+
ZSTR_SET_LITERAL_FAST(prefixed);
855+
return prefixed;
850856
} else {
851857
return zend_string_copy(name);
852858
}
@@ -3819,7 +3825,21 @@ static zend_result zend_compile_func_is_scalar(znode *result, zend_ast_list *arg
38193825
opline = zend_emit_op_tmp(result, ZEND_TYPE_CHECK, &arg_node, NULL);
38203826
opline->extended_value = (1 << IS_FALSE | 1 << IS_TRUE | 1 << IS_DOUBLE | 1 << IS_LONG | 1 << IS_STRING);
38213827
return SUCCESS;
3822-
}
3828+
} /* }}} */
3829+
3830+
static zend_result zend_compile_func_is_literal(znode *result, zend_ast_list *args) /* {{{ */
3831+
{
3832+
znode arg_node;
3833+
3834+
if (args->children != 1) {
3835+
return FAILURE;
3836+
}
3837+
3838+
zend_compile_expr(&arg_node, args->child[0]);
3839+
zend_emit_op(result, ZEND_LITERAL_CHECK, &arg_node, NULL);
3840+
3841+
return SUCCESS;
3842+
} /* }}} */
38233843

38243844
zend_result zend_compile_func_cast(znode *result, zend_ast_list *args, uint32_t type) /* {{{ */
38253845
{
@@ -4350,6 +4370,8 @@ zend_result zend_try_compile_special_func(znode *result, zend_string *lcname, ze
43504370
return zend_compile_func_typecheck(result, args, IS_RESOURCE);
43514371
} else if (zend_string_equals_literal(lcname, "is_scalar")) {
43524372
return zend_compile_func_is_scalar(result, args);
4373+
} else if (zend_string_equals_literal(lcname, "is_literal")) {
4374+
return zend_compile_func_is_literal(result, args);
43534375
} else if (zend_string_equals_literal(lcname, "boolval")) {
43544376
return zend_compile_func_cast(result, args, _IS_BOOL);
43554377
} else if (zend_string_equals_literal(lcname, "intval")) {

Zend/zend_language_scanner.l

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,15 @@ ZEND_API void zend_prepare_string_for_scanning(zval *str, zend_string *filename)
760760
RESET_DOC_COMMENT();
761761
}
762762

763+
zend_ast* zend_get_scanned_string_ast(zval *zendlval, uint32_t start_line) {
764+
if (Z_TYPE_P(zendlval) == IS_STRING && Z_STRLEN_P(zendlval) > 1) {
765+
zend_string *string =
766+
Z_STR_P(zendlval);
767+
768+
GC_TYPE_INFO(string) |= IS_STR_LITERAL;
769+
}
770+
return zend_ast_create_zval_with_lineno(zendlval, start_line);
771+
}
763772

764773
ZEND_API size_t zend_get_scanned_file_offset(void)
765774
{
@@ -895,7 +904,7 @@ ZEND_API void zend_multibyte_yyinput_again(zend_encoding_filter old_input_filter
895904
ZVAL_STRINGL(zendlval, s, sz); \
896905
efree(s); \
897906
} else if (yyleng == 1) { \
898-
ZVAL_INTERNED_STR(zendlval, ZSTR_CHAR((zend_uchar)*(yytext))); \
907+
ZVAL_INTERNED_STR(zendlval, ZSTR_LITERAL_CHAR((zend_uchar)*(yytext))); \
899908
} else { \
900909
ZVAL_STRINGL(zendlval, yytext, yyleng); \
901910
}
@@ -907,13 +916,13 @@ static zend_result zend_scan_escape_string(zval *zendlval, char *str, int len, c
907916

908917
if (len <= 1) {
909918
if (len < 1) {
910-
ZVAL_EMPTY_STRING(zendlval);
919+
ZVAL_INTERNED_STR(zendlval, ZSTR_EMPTY_LITERAL_ALLOC());
911920
} else {
912921
zend_uchar c = (zend_uchar)*str;
913922
if (c == '\n' || c == '\r') {
914923
CG(zend_lineno)++;
915924
}
916-
ZVAL_INTERNED_STR(zendlval, ZSTR_CHAR(c));
925+
ZVAL_INTERNED_STR(zendlval, ZSTR_LITERAL_CHAR(c));
917926
}
918927
goto skip_escape_conversion;
919928
}
@@ -1121,6 +1130,14 @@ skip_escape_conversion:
11211130
ZVAL_STRINGL(zendlval, (char *) str, sz);
11221131
efree(str);
11231132
}
1133+
1134+
if (UNEXPECTED(Z_STRLEN_P(zendlval) == 1)) {
1135+
zend_uchar c = (zend_uchar)*Z_STRVAL_P(zendlval);
1136+
1137+
zend_string_release(Z_STR_P(zendlval));
1138+
1139+
ZVAL_INTERNED_STR(zendlval, ZSTR_LITERAL_CHAR(c));
1140+
}
11241141
return SUCCESS;
11251142
}
11261143

@@ -2121,7 +2138,7 @@ string:
21212138

21222139
<ST_VAR_OFFSET>{LNUM}|{HNUM}|{BNUM}|{ONUM} { /* Offset must be treated as a string */
21232140
if (yyleng == 1) {
2124-
ZVAL_INTERNED_STR(zendlval, ZSTR_CHAR((zend_uchar)*(yytext)));
2141+
ZVAL_INTERNED_STR(zendlval, ZSTR_LITERAL_CHAR((zend_uchar)*(yytext)));
21252142
} else {
21262143
ZVAL_STRINGL(zendlval, yytext, yyleng);
21272144
}
@@ -2276,7 +2293,7 @@ inline_char_handler:
22762293
yyless(readsize);
22772294
}
22782295
} else if (yyleng == 1) {
2279-
ZVAL_INTERNED_STR(zendlval, ZSTR_CHAR((zend_uchar)*yytext));
2296+
ZVAL_INTERNED_STR(zendlval, ZSTR_LITERAL_CHAR((zend_uchar)*yytext));
22802297
} else {
22812298
ZVAL_STRINGL(zendlval, yytext, yyleng);
22822299
}
@@ -2451,13 +2468,13 @@ inline_char_handler:
24512468

24522469
if (yyleng-bprefix-2 <= 1) {
24532470
if (yyleng-bprefix-2 < 1) {
2454-
ZVAL_EMPTY_STRING(zendlval);
2471+
ZVAL_INTERNED_STR(zendlval, ZSTR_EMPTY_LITERAL_ALLOC());
24552472
} else {
24562473
zend_uchar c = (zend_uchar)*(yytext+bprefix+1);
24572474
if (c == '\n' || c == '\r') {
24582475
CG(zend_lineno)++;
24592476
}
2460-
ZVAL_INTERNED_STR(zendlval, ZSTR_CHAR(c));
2477+
ZVAL_INTERNED_STR(zendlval, ZSTR_LITERAL_CHAR(c));
24612478
}
24622479
goto skip_escape_conversion;
24632480
}
@@ -2515,6 +2532,15 @@ skip_escape_conversion:
25152532
zend_string_release_ex(Z_STR_P(zendlval), 0);
25162533
ZVAL_STR(zendlval, new_str);
25172534
}
2535+
2536+
if (UNEXPECTED(Z_STRLEN_P(zendlval) == 1)) {
2537+
zend_uchar c = (zend_uchar)*Z_STRVAL_P(zendlval);
2538+
2539+
zend_string_release(Z_STR_P(zendlval));
2540+
2541+
ZVAL_INTERNED_STR(zendlval, ZSTR_LITERAL_CHAR(c));
2542+
}
2543+
25182544
RETURN_TOKEN_WITH_VAL(T_CONSTANT_ENCAPSED_STRING);
25192545
}
25202546

@@ -3081,7 +3107,7 @@ emit_token_with_str:
30813107
emit_token_with_val:
30823108
if (PARSER_MODE()) {
30833109
ZEND_ASSERT(Z_TYPE_P(zendlval) != IS_UNDEF);
3084-
elem->ast = zend_ast_create_zval_with_lineno(zendlval, start_line);
3110+
elem->ast = zend_get_scanned_string_ast(zendlval, start_line);
30853111
}
30863112
30873113
emit_token:

Zend/zend_operators.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,10 +1870,15 @@ ZEND_API zend_result ZEND_FASTCALL concat_function(zval *result, zval *op1, zval
18701870
{
18711871
zval *orig_op1 = op1;
18721872
zval op1_copy, op2_copy;
1873+
bool literal = false;
18731874

18741875
ZVAL_UNDEF(&op1_copy);
18751876
ZVAL_UNDEF(&op2_copy);
18761877

1878+
if (UNEXPECTED(Z_IS_LITERAL_P(op1) && Z_IS_LITERAL_P(op2))) {
1879+
literal = true;
1880+
}
1881+
18771882
do {
18781883
if (UNEXPECTED(Z_TYPE_P(op1) != IS_STRING)) {
18791884
if (Z_ISREF_P(op1)) {
@@ -1950,12 +1955,18 @@ ZEND_API zend_result ZEND_FASTCALL concat_function(zval *result, zval *op1, zval
19501955
if (result == op1 && Z_REFCOUNTED_P(result)) {
19511956
/* special case, perform operations on result */
19521957
result_str = zend_string_extend(Z_STR_P(result), result_len, 0);
1958+
if (UNEXPECTED(!literal && ZSTR_IS_LITERAL(result_str))) {
1959+
ZSTR_UNSET_LITERAL(&result_str);
1960+
}
19531961
} else {
19541962
result_str = zend_string_alloc(result_len, 0);
19551963
memcpy(ZSTR_VAL(result_str), Z_STRVAL_P(op1), op1_len);
19561964
if (result == orig_op1) {
19571965
i_zval_ptr_dtor(result);
19581966
}
1967+
if (UNEXPECTED(literal)) {
1968+
ZSTR_SET_LITERAL_FAST(result_str);
1969+
}
19591970
}
19601971

19611972
/* This has to happen first to account for the cases where result == op1 == op2 and

0 commit comments

Comments
 (0)