- Reimplemented ZEND_INIT_FCALL_BY_NAME and ZEND_INIT_NS_FCALL_BY_NAME to use literals instead of additional operands

- Optimized access to global constants
This commit is contained in:
Dmitry Stogov 2010-04-27 12:09:13 +00:00
parent 194444b293
commit c58b131e29
5 changed files with 109 additions and 67 deletions

View File

@ -388,6 +388,37 @@ int zend_add_func_name_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC
} }
/* }}} */ /* }}} */
int zend_add_ns_func_name_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC) /* {{{ */
{
int ret;
char *lc_name, *ns_separator;
int lc_len;
zval c;
int lc_literal;
if (op_array->last_literal > 0 &&
&op_array->literals[op_array->last_literal - 1].constant == zv) {
/* we already have function name as last literal (do nothing) */
ret = op_array->last_literal - 1;
} else {
ret = zend_add_literal(op_array, zv);
}
lc_name = zend_str_tolower_dup(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
ZVAL_STRINGL(&c, lc_name, Z_STRLEN_P(zv), 0);
lc_literal = zend_add_literal(CG(active_op_array), &c);
CALCULATE_LITERAL_HASH(lc_literal);
ns_separator = zend_memrchr(Z_STRVAL_P(zv), '\\', Z_STRLEN_P(zv)) + 1;
lc_len = Z_STRLEN_P(zv) - (ns_separator - Z_STRVAL_P(zv));
lc_name = zend_str_tolower_dup(ns_separator, lc_len);
ZVAL_STRINGL(&c, lc_name, lc_len, 0);
lc_literal = zend_add_literal(CG(active_op_array), &c);
CALCULATE_LITERAL_HASH(lc_literal);
return ret;
}
/* }}} */
int zend_add_class_name_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC) /* {{{ */ int zend_add_class_name_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC) /* {{{ */
{ {
@ -1853,13 +1884,13 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_INIT_FCALL_BY_NAME; opline->opcode = ZEND_INIT_FCALL_BY_NAME;
SET_NODE(opline->op2, left_bracket); SET_NODE(opline->op2, left_bracket);
if (opline->op2_type == IS_CONST) { SET_UNUSED(opline->op1);
opline->op1_type = IS_CONST; if (left_bracket->op_type == IS_CONST) {
LITERAL_STRINGL(opline->op1, zend_str_tolower_dup(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))), Z_STRLEN(CONSTANT(opline->op2.constant)), 0); opline->op2_type = IS_CONST;
CALCULATE_LITERAL_HASH(opline->op1.constant); opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), &left_bracket->u.constant TSRMLS_CC);
} else { } else {
SET_UNUSED(opline->op1); SET_NODE(opline->op2, left_bracket);
} }
} }
zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *)); zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
@ -1883,7 +1914,7 @@ void zend_do_clone(znode *result, const znode *expr TSRMLS_DC) /* {{{ */
void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRMLS_DC) /* {{{ */ void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRMLS_DC) /* {{{ */
{ {
unsigned char *ptr = NULL; unsigned char *ptr = NULL;
zend_op *opline, *opline2; zend_op *opline;
opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline = get_next_op(CG(active_op_array) TSRMLS_CC);
if (ns_call) { if (ns_call) {
@ -1892,34 +1923,18 @@ void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRML
/* In run-time PHP will check for function with full name and /* In run-time PHP will check for function with full name and
internal function with short name */ internal function with short name */
opline->opcode = ZEND_INIT_NS_FCALL_BY_NAME; opline->opcode = ZEND_INIT_NS_FCALL_BY_NAME;
SET_NODE(opline->op2, function_name); SET_UNUSED(opline->op1);
opline->op1_type = IS_CONST; opline->op2_type = IS_CONST;
LITERAL_STRINGL(opline->op1, zend_str_tolower_dup(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))), Z_STRLEN(CONSTANT(opline->op2.constant)), 0); opline->op2.constant = zend_add_ns_func_name_literal(CG(active_op_array), &function_name->u.constant TSRMLS_CC);
CALCULATE_LITERAL_HASH(opline->op1.constant);
slash = zend_memrchr(Z_STRVAL(CONSTANT(opline->op1.constant)), '\\', Z_STRLEN(CONSTANT(opline->op1.constant)));
prefix_len = slash-Z_STRVAL(CONSTANT(opline->op1.constant))+1;
name_len = Z_STRLEN(CONSTANT(opline->op1.constant))-prefix_len;
opline2 = get_next_op(CG(active_op_array) TSRMLS_CC);
opline2->opcode = ZEND_OP_DATA;
SET_UNUSED(opline2->op1);
if(!slash) {
zend_error(E_CORE_ERROR, "Namespaced name %s should contain slash", Z_STRVAL(CONSTANT(opline->op1.constant)));
}
/* this is the length of namespace prefix */
opline2->op1.num = prefix_len;
/* this is the hash of the non-prefixed part, lowercased */
opline2->extended_value = zend_hash_func(slash+1, name_len+1);
SET_UNUSED(opline2->op2);
} else { } else {
opline->opcode = ZEND_INIT_FCALL_BY_NAME; opline->opcode = ZEND_INIT_FCALL_BY_NAME;
SET_NODE(opline->op2, function_name); SET_UNUSED(opline->op1);
if (opline->op2_type == IS_CONST) { if (function_name->op_type == IS_CONST) {
opline->op1_type = IS_CONST; opline->op2_type = IS_CONST;
LITERAL_STRINGL(opline->op1, zend_str_tolower_dup(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))), Z_STRLEN(CONSTANT(opline->op2.constant)), 0); opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), &function_name->u.constant TSRMLS_CC);
CALCULATE_LITERAL_HASH(opline->op1.constant); } else {
} else { SET_NODE(opline->op2, function_name);
SET_UNUSED(opline->op1); }
}
} }
zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *)); zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));

View File

@ -413,7 +413,7 @@ finish:
return zend_get_constant(name, name_len, result TSRMLS_CC); return zend_get_constant(name, name_len, result TSRMLS_CC);
} }
int zend_quick_get_constant(const zend_literal *key, zval *result, ulong flags TSRMLS_DC) zend_constant *zend_quick_get_constant(const zend_literal *key, ulong flags TSRMLS_DC)
{ {
zend_constant *c; zend_constant *c;
@ -430,22 +430,19 @@ int zend_quick_get_constant(const zend_literal *key, zval *result, ulong flags T
key--; key--;
if (!zend_get_halt_offset_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) { if (!zend_get_halt_offset_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) {
return 0; return NULL;
} }
} }
} }
} else { } else {
key--; key--;
if (!zend_get_halt_offset_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) { if (!zend_get_halt_offset_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) {
return 0; return NULL;
} }
} }
} }
} }
return c;
INIT_PZVAL_COPY(result, &c->value);
zval_copy_ctor(result);
return 1;
} }
ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC) ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)

View File

@ -69,7 +69,7 @@ ZEND_API void zend_register_stringl_constant(const char *name, uint name_len, ch
ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC); ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC);
void zend_copy_constants(HashTable *target, HashTable *sourc); void zend_copy_constants(HashTable *target, HashTable *sourc);
void copy_zend_constant(zend_constant *c); void copy_zend_constant(zend_constant *c);
int zend_quick_get_constant(const zend_literal *key, zval *result, ulong flags TSRMLS_DC); zend_constant *zend_quick_get_constant(const zend_literal *key, ulong flags TSRMLS_DC);
END_EXTERN_C() END_EXTERN_C()
#define ZEND_CONSTANT_DTOR (void (*)(void *)) free_zend_constant #define ZEND_CONSTANT_DTOR (void (*)(void *)) free_zend_constant

View File

@ -2320,7 +2320,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (OP2_TYPE == IS_CONST) { if (OP2_TYPE == IS_CONST) {
function_name = opline->op1.zv; function_name = (zval*)(opline->op2.literal+1);
if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) { if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
SAVE_OPLINE(); SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv)); zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
@ -2373,19 +2373,20 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST) ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST)
{ {
USE_OPLINE USE_OPLINE
zend_literal *func_name;
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (zend_hash_quick_find(EG(function_table), Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv)+1, Z_HASH_P(opline->op1.zv), (void **) &EX(fbc))==FAILURE) {
char *short_name = Z_STRVAL_P(opline->op1.zv) + (opline+1)->op1.num; func_name = opline->op2.literal + 1;
if (UNEXPECTED(zend_hash_quick_find(EG(function_table), short_name, Z_STRLEN_P(opline->op1.zv) - (opline+1)->op1.num+1, (opline+1)->extended_value, (void **) &EX(fbc))==FAILURE)) { if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE) {
func_name++;
if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE)) {
SAVE_OPLINE(); SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv)); zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} }
} }
EX(object) = NULL; EX(object) = NULL;
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE(); ZEND_VM_NEXT_OPCODE();
} }
@ -3335,8 +3336,10 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
SAVE_OPLINE(); SAVE_OPLINE();
if (OP1_TYPE == IS_UNUSED) { if (OP1_TYPE == IS_UNUSED) {
/* namespaced constant */ zend_constant *c;
if (!zend_quick_get_constant(opline->op2.literal + 1, &EX_T(opline->result.var).tmp_var, opline->extended_value TSRMLS_CC)) { zval *retval;
if ((c = zend_quick_get_constant(opline->op2.literal + 1, opline->extended_value TSRMLS_CC)) == NULL) {
if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {
char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv)); char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv));
if(!actual) { if(!actual) {
@ -3347,10 +3350,15 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
/* non-qualified constant - allow text substitution */ /* non-qualified constant - allow text substitution */
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual);
ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1); ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else { } else {
zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv)); zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv));
} }
} }
retval = &EX_T(opline->result.var).tmp_var;
INIT_PZVAL_COPY(retval, &c->value);
zval_copy_ctor(retval);
CHECK_EXCEPTION(); CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE(); ZEND_VM_NEXT_OPCODE();
} else { } else {

View File

@ -871,7 +871,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CONST == IS_CONST) { if (IS_CONST == IS_CONST) {
function_name = opline->op1.zv; function_name = (zval*)(opline->op2.literal+1);
if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) { if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
SAVE_OPLINE(); SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv)); zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
@ -924,19 +924,20 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
static int ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{ {
USE_OPLINE USE_OPLINE
zend_literal *func_name;
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (zend_hash_quick_find(EG(function_table), Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv)+1, Z_HASH_P(opline->op1.zv), (void **) &EX(fbc))==FAILURE) { func_name = opline->op2.literal + 1;
char *short_name = Z_STRVAL_P(opline->op1.zv) + (opline+1)->op1.num; if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE) {
if (UNEXPECTED(zend_hash_quick_find(EG(function_table), short_name, Z_STRLEN_P(opline->op1.zv) - (opline+1)->op1.num+1, (opline+1)->extended_value, (void **) &EX(fbc))==FAILURE)) { func_name++;
if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE)) {
SAVE_OPLINE(); SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv)); zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} }
} }
EX(object) = NULL; EX(object) = NULL;
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE(); ZEND_VM_NEXT_OPCODE();
} }
@ -1084,7 +1085,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_TMP_VAR == IS_CONST) { if (IS_TMP_VAR == IS_CONST) {
function_name = opline->op1.zv; function_name = (zval*)(opline->op2.literal+1);
if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) { if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
SAVE_OPLINE(); SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv)); zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
@ -1197,7 +1198,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_VAR == IS_CONST) { if (IS_VAR == IS_CONST) {
function_name = opline->op1.zv; function_name = (zval*)(opline->op2.literal+1);
if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) { if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
SAVE_OPLINE(); SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv)); zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
@ -1338,7 +1339,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CV == IS_CONST) { if (IS_CV == IS_CONST) {
function_name = opline->op1.zv; function_name = (zval*)(opline->op2.literal+1);
if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) { if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
SAVE_OPLINE(); SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv)); zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
@ -3009,8 +3010,10 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
SAVE_OPLINE(); SAVE_OPLINE();
if (IS_CONST == IS_UNUSED) { if (IS_CONST == IS_UNUSED) {
/* namespaced constant */ zend_constant *c;
if (!zend_quick_get_constant(opline->op2.literal + 1, &EX_T(opline->result.var).tmp_var, opline->extended_value TSRMLS_CC)) { zval *retval;
if ((c = zend_quick_get_constant(opline->op2.literal + 1, opline->extended_value TSRMLS_CC)) == NULL) {
if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {
char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv)); char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv));
if(!actual) { if(!actual) {
@ -3021,10 +3024,15 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
/* non-qualified constant - allow text substitution */ /* non-qualified constant - allow text substitution */
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual);
ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1); ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else { } else {
zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv)); zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv));
} }
} }
retval = &EX_T(opline->result.var).tmp_var;
INIT_PZVAL_COPY(retval, &c->value);
zval_copy_ctor(retval);
CHECK_EXCEPTION(); CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE(); ZEND_VM_NEXT_OPCODE();
} else { } else {
@ -11530,8 +11538,10 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
SAVE_OPLINE(); SAVE_OPLINE();
if (IS_VAR == IS_UNUSED) { if (IS_VAR == IS_UNUSED) {
/* namespaced constant */ zend_constant *c;
if (!zend_quick_get_constant(opline->op2.literal + 1, &EX_T(opline->result.var).tmp_var, opline->extended_value TSRMLS_CC)) { zval *retval;
if ((c = zend_quick_get_constant(opline->op2.literal + 1, opline->extended_value TSRMLS_CC)) == NULL) {
if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {
char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv)); char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv));
if(!actual) { if(!actual) {
@ -11542,10 +11552,15 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
/* non-qualified constant - allow text substitution */ /* non-qualified constant - allow text substitution */
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual);
ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1); ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else { } else {
zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv)); zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv));
} }
} }
retval = &EX_T(opline->result.var).tmp_var;
INIT_PZVAL_COPY(retval, &c->value);
zval_copy_ctor(retval);
CHECK_EXCEPTION(); CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE(); ZEND_VM_NEXT_OPCODE();
} else { } else {
@ -19416,8 +19431,10 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
SAVE_OPLINE(); SAVE_OPLINE();
if (IS_UNUSED == IS_UNUSED) { if (IS_UNUSED == IS_UNUSED) {
/* namespaced constant */ zend_constant *c;
if (!zend_quick_get_constant(opline->op2.literal + 1, &EX_T(opline->result.var).tmp_var, opline->extended_value TSRMLS_CC)) { zval *retval;
if ((c = zend_quick_get_constant(opline->op2.literal + 1, opline->extended_value TSRMLS_CC)) == NULL) {
if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {
char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv)); char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv));
if(!actual) { if(!actual) {
@ -19428,10 +19445,15 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
/* non-qualified constant - allow text substitution */ /* non-qualified constant - allow text substitution */
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual);
ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1); ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else { } else {
zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv)); zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv));
} }
} }
retval = &EX_T(opline->result.var).tmp_var;
INIT_PZVAL_COPY(retval, &c->value);
zval_copy_ctor(retval);
CHECK_EXCEPTION(); CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE(); ZEND_VM_NEXT_OPCODE();
} else { } else {