summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2018-07-17 12:01:14 +0200
committerAnatol Belski <ab@php.net>2018-07-17 12:01:14 +0200
commitca50aa9ca8a37e63ce64043e3e33fc5af2c19893 (patch)
tree87456acdac86c5bf1d46619f90341a086e54639b
parentb1f4f5c80cc000931093340f7e4412d18af928fc (diff)
parent88dd38ee814f242befa7f9f40599b7b22b5ff8c8 (diff)
downloadphp-git-ca50aa9ca8a37e63ce64043e3e33fc5af2c19893.tar.gz
Merge branch 'master' of git.php.net:php-src
-rw-r--r--Zend/zend_constants.c50
-rw-r--r--Zend/zend_constants.h2
-rw-r--r--Zend/zend_execute.c113
-rw-r--r--Zend/zend_vm_def.h42
-rw-r--r--Zend/zend_vm_execute.h42
5 files changed, 123 insertions, 126 deletions
diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c
index 8b68858ad4..48b01863ea 100644
--- a/Zend/zend_constants.c
+++ b/Zend/zend_constants.c
@@ -478,56 +478,6 @@ failure:
return &c->value;
}
-ZEND_API zend_constant* ZEND_FASTCALL zend_quick_get_constant(
- const zval *key, uint32_t flags, zend_bool *is_deprecated)
-{
- zval *zv;
- const zval *orig_key = key;
- zend_constant *c = NULL;
-
- zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1);
- if (zv) {
- c = (zend_constant*)Z_PTR_P(zv);
- } else {
- key++;
- zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1);
- if (zv && (((zend_constant*)Z_PTR_P(zv))->flags & CONST_CS) == 0) {
- c = (zend_constant*)Z_PTR_P(zv);
- } else {
- if ((flags & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) {
- key++;
- zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1);
- if (zv) {
- c = (zend_constant*)Z_PTR_P(zv);
- } else {
- key++;
- zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1);
- if (zv && (((zend_constant*)Z_PTR_P(zv))->flags & CONST_CS) == 0) {
- c = (zend_constant*)Z_PTR_P(zv);
- }
- }
- }
- }
- }
-
- if (!c) {
- return NULL;
- }
-
- if (is_deprecated) {
- if (c->flags & (CONST_CS|CONST_CT_SUBST)) {
- /* Constant is case-sensitive or true/false/null */
- *is_deprecated = 0;
- } else {
- zend_bool ns_fallback = key >= orig_key + 2;
- const zval *access_key = ns_fallback ? orig_key + 2 : orig_key - 1;
- *is_deprecated = is_access_deprecated(c, Z_STRVAL_P(access_key));
- }
- }
-
- return c;
-}
-
static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_constant *c)
{
void *ret;
diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h
index e06d91ee14..b8112d33a1 100644
--- a/Zend/zend_constants.h
+++ b/Zend/zend_constants.h
@@ -82,8 +82,6 @@ ZEND_API int zend_register_constant(zend_constant *c);
#ifdef ZTS
void zend_copy_constants(HashTable *target, HashTable *sourc);
#endif
-ZEND_API zend_constant* ZEND_FASTCALL zend_quick_get_constant(
- const zval *key, uint32_t flags, zend_bool *is_deprecated);
END_EXTERN_C()
#define ZEND_CONSTANT_DTOR free_zend_constant
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 0778c19ddd..6abdc4c2ca 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -3285,6 +3285,119 @@ static zend_never_inline zend_bool ZEND_FASTCALL zend_fe_reset_iterator(zval *ar
}
/* }}} */
+static zend_always_inline int _zend_quick_get_constant(
+ const zval *key, uint32_t flags, int check_defined_only OPLINE_DC EXECUTE_DATA_DC) /* {{{ */
+{
+ zval *zv;
+ const zval *orig_key = key;
+ zend_constant *c = NULL;
+
+ zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1);
+ if (zv) {
+ c = (zend_constant*)Z_PTR_P(zv);
+ } else {
+ key++;
+ zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1);
+ if (zv && (((zend_constant*)Z_PTR_P(zv))->flags & CONST_CS) == 0) {
+ c = (zend_constant*)Z_PTR_P(zv);
+ } else {
+ if ((flags & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) {
+ key++;
+ zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1);
+ if (zv) {
+ c = (zend_constant*)Z_PTR_P(zv);
+ } else {
+ key++;
+ zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1);
+ if (zv && (((zend_constant*)Z_PTR_P(zv))->flags & CONST_CS) == 0) {
+ c = (zend_constant*)Z_PTR_P(zv);
+ }
+ }
+ }
+ }
+ }
+
+ if (!c) {
+ if (!check_defined_only) {
+ if ((opline->op1.num & IS_CONSTANT_UNQUALIFIED) != 0) {
+ char *actual = (char *)zend_memrchr(Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)), '\\', Z_STRLEN_P(RT_CONSTANT(opline, opline->op2)));
+ if (!actual) {
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(RT_CONSTANT(opline, opline->op2)));
+ } else {
+ actual++;
+ ZVAL_STRINGL(EX_VAR(opline->result.var),
+ actual, Z_STRLEN_P(RT_CONSTANT(opline, opline->op2)) - (actual - Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))));
+ }
+ /* non-qualified constant - allow text substitution */
+ zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)",
+ Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var)));
+ } else {
+ zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)));
+ ZVAL_UNDEF(EX_VAR(opline->result.var));
+ }
+ }
+ return FAILURE;
+ }
+
+ if (!check_defined_only) {
+ ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value);
+ if (!(c->flags & (CONST_CS|CONST_CT_SUBST))) {
+ const char *ns_sep;
+ size_t shortname_offset;
+ size_t shortname_len;
+ zend_bool is_deprecated;
+
+ if (flags & IS_CONSTANT_UNQUALIFIED) {
+ const zval *access_key;
+
+ if (!(flags & IS_CONSTANT_IN_NAMESPACE)) {
+ access_key = orig_key - 1;
+ } else {
+ if (key < orig_key + 2) {
+ goto check_short_name;
+ } else {
+ access_key = orig_key + 2;
+ }
+ }
+ is_deprecated = !zend_string_equals(c->name, Z_STR_P(access_key));
+ } else {
+check_short_name:
+ ns_sep = zend_memrchr(ZSTR_VAL(c->name), '\\', ZSTR_LEN(c->name));
+ ZEND_ASSERT(ns_sep);
+ /* Namespaces are always case-insensitive. Only compare shortname. */
+ shortname_offset = ns_sep - ZSTR_VAL(c->name) + 1;
+ shortname_len = ZSTR_LEN(c->name) - shortname_offset;
+
+ is_deprecated = memcmp(ZSTR_VAL(c->name) + shortname_offset, Z_STRVAL_P(orig_key - 1) + shortname_offset, shortname_len) != 0;
+ }
+
+ if (is_deprecated) {
+ zend_error(E_DEPRECATED,
+ "Case-insensitive constants are deprecated. "
+ "The correct casing for this constant is \"%s\"",
+ ZSTR_VAL(c->name));
+ return SUCCESS;
+ }
+ }
+ }
+
+ CACHE_PTR(opline->extended_value, c);
+ return SUCCESS;
+}
+/* }}} */
+
+static zend_never_inline void ZEND_FASTCALL zend_quick_get_constant(
+ const zval *key, uint32_t flags OPLINE_DC EXECUTE_DATA_DC) /* {{{ */
+{
+ _zend_quick_get_constant(key, flags, 0 OPLINE_CC EXECUTE_DATA_CC);
+}
+
+static zend_never_inline int ZEND_FASTCALL zend_quick_check_constant(
+ const zval *key, uint32_t flags OPLINE_DC EXECUTE_DATA_DC) /* {{{ */
+{
+ return _zend_quick_get_constant(key, flags, 1 OPLINE_CC EXECUTE_DATA_CC);
+}
+
#ifdef ZEND_VM_TRACE_HANDLERS
# include "zend_vm_trace_handlers.h"
#elif defined(ZEND_VM_TRACE_MAP)
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 3d0fdc0182..087dd3ac84 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5045,47 +5045,16 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED|CONST_FETCH, CONST, CACHE_SLOT)
{
USE_OPLINE
zend_constant *c;
- zend_bool is_deprecated;
c = CACHED_PTR(opline->extended_value);
if (EXPECTED(c != NULL) && EXPECTED(!IS_SPECIAL_CACHE_VAL(c))) {
- /* pass */
- } else if (UNEXPECTED((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num, &is_deprecated)) == NULL)) {
- SAVE_OPLINE();
-
- if ((opline->op1.num & IS_CONSTANT_UNQUALIFIED) != 0) {
- char *actual = (char *)zend_memrchr(Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)), '\\', Z_STRLEN_P(RT_CONSTANT(opline, opline->op2)));
- if (!actual) {
- ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(RT_CONSTANT(opline, opline->op2)));
- } else {
- actual++;
- ZVAL_STRINGL(EX_VAR(opline->result.var),
- actual, Z_STRLEN_P(RT_CONSTANT(opline, opline->op2)) - (actual - Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))));
- }
- /* non-qualified constant - allow text substitution */
- zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)",
- Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var)));
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
- } else {
- zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)));
- ZVAL_UNDEF(EX_VAR(opline->result.var));
- HANDLE_EXCEPTION();
- }
- } else if (is_deprecated) {
- SAVE_OPLINE();
- zend_error(E_DEPRECATED,
- "Case-insensitive constants are deprecated. "
- "The correct casing for this constant is \"%s\"",
- ZSTR_VAL(c->name));
ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
- } else {
- CACHE_PTR(opline->extended_value, c);
+ ZEND_VM_NEXT_OPCODE();
}
- ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value);
-
- ZEND_VM_NEXT_OPCODE();
+ SAVE_OPLINE();
+ zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num OPLINE_CC EXECUTE_DATA_CC);
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CONST, CACHE_SLOT)
@@ -7620,11 +7589,10 @@ ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY, CACHE_SLOT)
break;
}
}
- if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0, NULL)) == NULL) {
+ if (zend_quick_check_constant(RT_CONSTANT(opline, opline->op1), ZEND_GET_CONSTANT_NO_DEPRECATION_CHECK OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants))));
result = 0;
} else {
- CACHE_PTR(opline->extended_value, c);
result = 1;
}
} while (0);
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index c5598d6da7..a177bcea0f 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -3883,11 +3883,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST_HANDLER(ZEN
break;
}
}
- if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0, NULL)) == NULL) {
+ if (zend_quick_check_constant(RT_CONSTANT(opline, opline->op1), ZEND_GET_CONSTANT_NO_DEPRECATION_CHECK OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants))));
result = 0;
} else {
- CACHE_PTR(opline->extended_value, c);
result = 1;
}
} while (0);
@@ -31965,47 +31964,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON
{
USE_OPLINE
zend_constant *c;
- zend_bool is_deprecated;
c = CACHED_PTR(opline->extended_value);
if (EXPECTED(c != NULL) && EXPECTED(!IS_SPECIAL_CACHE_VAL(c))) {
- /* pass */
- } else if (UNEXPECTED((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num, &is_deprecated)) == NULL)) {
- SAVE_OPLINE();
-
- if ((opline->op1.num & IS_CONSTANT_UNQUALIFIED) != 0) {
- char *actual = (char *)zend_memrchr(Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)), '\\', Z_STRLEN_P(RT_CONSTANT(opline, opline->op2)));
- if (!actual) {
- ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(RT_CONSTANT(opline, opline->op2)));
- } else {
- actual++;
- ZVAL_STRINGL(EX_VAR(opline->result.var),
- actual, Z_STRLEN_P(RT_CONSTANT(opline, opline->op2)) - (actual - Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))));
- }
- /* non-qualified constant - allow text substitution */
- zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)",
- Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var)));
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
- } else {
- zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)));
- ZVAL_UNDEF(EX_VAR(opline->result.var));
- HANDLE_EXCEPTION();
- }
- } else if (is_deprecated) {
- SAVE_OPLINE();
- zend_error(E_DEPRECATED,
- "Case-insensitive constants are deprecated. "
- "The correct casing for this constant is \"%s\"",
- ZSTR_VAL(c->name));
ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
- } else {
- CACHE_PTR(opline->extended_value, c);
+ ZEND_VM_NEXT_OPCODE();
}
- ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value);
-
- ZEND_VM_NEXT_OPCODE();
+ SAVE_OPLINE();
+ zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num OPLINE_CC EXECUTE_DATA_CC);
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)