diff options
Diffstat (limited to 'Zend/zend_vm_execute.h')
-rw-r--r-- | Zend/zend_vm_execute.h | 303 |
1 files changed, 214 insertions, 89 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index abcd410a3e..6f4ef773f5 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -294,6 +294,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC); if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { + zend_error_handling error_handling; ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr); EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr; EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference; @@ -308,12 +309,14 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR arg_count--; } } + zend_save_error_handling(&error_handling TSRMLS_CC); if (!zend_execute_internal) { /* saves one function call if zend_execute_internal is not used */ ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); } else { zend_execute_internal(execute_data, RETURN_VALUE_USED(opline) TSRMLS_CC); } + zend_restore_error_handling(&error_handling TSRMLS_CC); if (!RETURN_VALUE_USED(opline)) { zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr); @@ -361,7 +364,10 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR /* Not sure what should be done here if it's a static method */ if (EX(object)) { + zend_error_handling error_handling; + zend_save_error_handling(&error_handling TSRMLS_CC); Z_OBJ_HT_P(EX(object))->call_method(EX(function_state).function->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); + zend_restore_error_handling(&error_handling TSRMLS_CC); } else { zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object"); } @@ -749,7 +755,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE if (Z_TYPE_P(function_name) == IS_OBJECT && Z_OBJ_HANDLER_P(function_name, get_closure) && - Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) { + Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object), NULL TSRMLS_CC) == SUCCESS) { if (EX(object)) { Z_ADDREF_P(EX(object)); } @@ -762,10 +768,11 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE } function_name_strval = Z_STRVAL_P(function_name); function_name_strlen = Z_STRLEN_P(function_name); - if (function_name_strval[0] == '\\') { + if (function_name_strval[0] == ':' && + function_name_strval[1] == ':') { - function_name_strlen -= 1; - lcname = zend_str_tolower_dup(function_name_strval + 1, function_name_strlen); + function_name_strlen -= 2; + lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen); } else { lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen); } @@ -790,8 +797,8 @@ static int ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPC 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(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc))==FAILURE) { - char *short_name = Z_STRVAL(opline->op1.u.constant)+Z_LVAL(op_data->op1.u.constant); - if (zend_hash_quick_find(EG(function_table), short_name, Z_STRLEN(opline->op1.u.constant)-Z_LVAL(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==FAILURE) { + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==FAILURE || + EX(fbc)->type != ZEND_INTERNAL_FUNCTION) { zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL(opline->op2.u.constant)); } } @@ -946,7 +953,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H if (Z_TYPE_P(function_name) == IS_OBJECT && Z_OBJ_HANDLER_P(function_name, get_closure) && - Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) { + Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object), NULL TSRMLS_CC) == SUCCESS) { if (EX(object)) { Z_ADDREF_P(EX(object)); } @@ -959,10 +966,11 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H } function_name_strval = Z_STRVAL_P(function_name); function_name_strlen = Z_STRLEN_P(function_name); - if (function_name_strval[0] == '\\') { + if (function_name_strval[0] == ':' && + function_name_strval[1] == ':') { - function_name_strlen -= 1; - lcname = zend_str_tolower_dup(function_name_strval + 1, function_name_strlen); + function_name_strlen -= 2; + lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen); } else { lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen); } @@ -1051,7 +1059,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H if (Z_TYPE_P(function_name) == IS_OBJECT && Z_OBJ_HANDLER_P(function_name, get_closure) && - Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) { + Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object), NULL TSRMLS_CC) == SUCCESS) { if (EX(object)) { Z_ADDREF_P(EX(object)); } @@ -1064,10 +1072,11 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H } function_name_strval = Z_STRVAL_P(function_name); function_name_strlen = Z_STRLEN_P(function_name); - if (function_name_strval[0] == '\\') { + if (function_name_strval[0] == ':' && + function_name_strval[1] == ':') { - function_name_strlen -= 1; - lcname = zend_str_tolower_dup(function_name_strval + 1, function_name_strlen); + function_name_strlen -= 2; + lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen); } else { lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen); } @@ -1184,7 +1193,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA if (Z_TYPE_P(function_name) == IS_OBJECT && Z_OBJ_HANDLER_P(function_name, get_closure) && - Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) { + Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object), NULL TSRMLS_CC) == SUCCESS) { if (EX(object)) { Z_ADDREF_P(EX(object)); } @@ -1197,10 +1206,11 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA } function_name_strval = Z_STRVAL_P(function_name); function_name_strlen = Z_STRLEN_P(function_name); - if (function_name_strval[0] == '\\') { + if (function_name_strval[0] == ':' && + function_name_strval[1] == ':') { - function_name_strlen -= 1; - lcname = zend_str_tolower_dup(function_name_strval + 1, function_name_strlen); + function_name_strlen -= 2; + lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen); } else { lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen); } @@ -2594,9 +2604,16 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER( zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + /* try a function in namespace */ + zend_op *op_data = opline+1; ZEND_VM_INC_OPCODE(); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); + } + /* no function found. try a static method in class */ ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC); if (!ce) { @@ -2613,7 +2630,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER( } } if(IS_CONST != IS_UNUSED) { - char *function_name_strval = NULL; + char *function_name_strval; int function_name_strlen = 0; @@ -2631,7 +2648,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER( } } - if (function_name_strval) { + if (function_name_strlen) { if (ce->get_static_method) { EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } else { @@ -2721,31 +2738,46 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO zend_op *opline = EX(opline); if (IS_CONST == IS_UNUSED) { - /* namespaced constant */ - if (!zend_get_constant_ex(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var, NULL, opline->extended_value TSRMLS_CC)) { - if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { - char *actual = (char *)zend_memrchr(Z_STRVAL(opline->op2.u.constant), '\\', Z_STRLEN(opline->op2.u.constant)); - if(!actual) { - actual = Z_STRVAL(opline->op2.u.constant); - } else { - actual++; - } - /* non-qualified constant - allow text substitution */ - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); - ZVAL_STRINGL(&EX_T(opline->result.u.var).tmp_var, actual, Z_STRLEN(opline->op2.u.constant)-(actual - Z_STRVAL(opline->op2.u.constant)), 1); - } else { - zend_error_noreturn(E_ERROR, "Undefined constant '%s'", - Z_STRVAL(opline->op2.u.constant), Z_STRVAL(opline->op2.u.constant)); - } + if (!zend_get_constant(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) { + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { + zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL(opline->op2.u.constant)); + } + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", + Z_STRVAL(opline->op2.u.constant), + Z_STRVAL(opline->op2.u.constant)); + EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant; + zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var); } ZEND_VM_NEXT_OPCODE(); } else { - /* class constant */ zend_class_entry *ce; zval **value; if (IS_CONST == IS_CONST) { + zend_op *op_data = opline + 1; + zend_constant *c; + ZEND_VM_INC_OPCODE(); + + /* try a constant in namespace */ + if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &c)==SUCCESS) { + EX_T(opline->result.u.var).tmp_var = c->value; + zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var); + ZEND_VM_NEXT_OPCODE(); + } else if ((opline->extended_value & IS_CONSTANT_RT_NS_CHECK) != 0) { + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { + zend_error_noreturn(E_ERROR, "Undefined constant '%s::%s'", Z_STRVAL(opline->op1.u.constant), Z_STRVAL(opline->op2.u.constant)); + } else if (!zend_get_constant(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) { + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", + Z_STRVAL(opline->op2.u.constant), + Z_STRVAL(opline->op2.u.constant)); + EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant; + zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var); + } + ZEND_VM_NEXT_OPCODE(); + } + + /* no constant found. try a constant in class */ ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC); if (!ce) { zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL(opline->op2.u.constant)); @@ -3168,9 +3200,16 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_CONST == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* try a function in namespace */ + zend_op *op_data = opline+1; ZEND_VM_INC_OPCODE(); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); + } + /* no function found. try a static method in class */ ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC); if (!ce) { @@ -3187,7 +3226,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE } } if(IS_TMP_VAR != IS_UNUSED) { - char *function_name_strval = NULL; + char *function_name_strval; int function_name_strlen = 0; zend_free_op free_op2; @@ -3205,7 +3244,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE } } - if (function_name_strval) { + if (function_name_strlen) { if (ce->get_static_method) { EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } else { @@ -3637,9 +3676,16 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_CONST == IS_CONST && IS_VAR == IS_CONST) { + /* try a function in namespace */ + zend_op *op_data = opline+1; ZEND_VM_INC_OPCODE(); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); + } + /* no function found. try a static method in class */ ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC); if (!ce) { @@ -3656,7 +3702,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE } } if(IS_VAR != IS_UNUSED) { - char *function_name_strval = NULL; + char *function_name_strval; int function_name_strlen = 0; zend_free_op free_op2; @@ -3674,7 +3720,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE } } - if (function_name_strval) { + if (function_name_strlen) { if (ce->get_static_method) { EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } else { @@ -3862,9 +3908,16 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_CONST == IS_CONST && IS_UNUSED == IS_CONST) { + /* try a function in namespace */ + zend_op *op_data = opline+1; ZEND_VM_INC_OPCODE(); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); + } + /* no function found. try a static method in class */ ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC); if (!ce) { @@ -3881,7 +3934,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER } } if(IS_UNUSED != IS_UNUSED) { - char *function_name_strval = NULL; + char *function_name_strval; int function_name_strlen = 0; @@ -3899,7 +3952,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER } } - if (function_name_strval) { + if (function_name_strlen) { if (ce->get_static_method) { EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } else { @@ -4299,9 +4352,16 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_CONST == IS_CONST && IS_CV == IS_CONST) { + /* try a function in namespace */ + zend_op *op_data = opline+1; ZEND_VM_INC_OPCODE(); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); + } + /* no function found. try a static method in class */ ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC); if (!ce) { @@ -4318,7 +4378,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN } } if(IS_CV != IS_UNUSED) { - char *function_name_strval = NULL; + char *function_name_strval; int function_name_strlen = 0; @@ -4336,7 +4396,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN } } - if (function_name_strval) { + if (function_name_strlen) { if (ce->get_static_method) { EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } else { @@ -10285,9 +10345,16 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_VAR == IS_CONST && IS_CONST == IS_CONST) { + /* try a function in namespace */ + zend_op *op_data = opline+1; ZEND_VM_INC_OPCODE(); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); + } + /* no function found. try a static method in class */ ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC); if (!ce) { @@ -10304,7 +10371,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE } } if(IS_CONST != IS_UNUSED) { - char *function_name_strval = NULL; + char *function_name_strval; int function_name_strlen = 0; @@ -10322,7 +10389,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE } } - if (function_name_strval) { + if (function_name_strlen) { if (ce->get_static_method) { EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } else { @@ -10412,31 +10479,46 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE zend_op *opline = EX(opline); if (IS_VAR == IS_UNUSED) { - /* namespaced constant */ - if (!zend_get_constant_ex(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var, NULL, opline->extended_value TSRMLS_CC)) { - if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { - char *actual = (char *)zend_memrchr(Z_STRVAL(opline->op2.u.constant), '\\', Z_STRLEN(opline->op2.u.constant)); - if(!actual) { - actual = Z_STRVAL(opline->op2.u.constant); - } else { - actual++; - } - /* non-qualified constant - allow text substitution */ - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); - ZVAL_STRINGL(&EX_T(opline->result.u.var).tmp_var, actual, Z_STRLEN(opline->op2.u.constant)-(actual - Z_STRVAL(opline->op2.u.constant)), 1); - } else { - zend_error_noreturn(E_ERROR, "Undefined constant '%s'", - Z_STRVAL(opline->op2.u.constant), Z_STRVAL(opline->op2.u.constant)); - } + if (!zend_get_constant(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) { + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { + zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL(opline->op2.u.constant)); + } + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", + Z_STRVAL(opline->op2.u.constant), + Z_STRVAL(opline->op2.u.constant)); + EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant; + zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var); } ZEND_VM_NEXT_OPCODE(); } else { - /* class constant */ zend_class_entry *ce; zval **value; if (IS_VAR == IS_CONST) { + zend_op *op_data = opline + 1; + zend_constant *c; + + ZEND_VM_INC_OPCODE(); + + /* try a constant in namespace */ + if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &c)==SUCCESS) { + EX_T(opline->result.u.var).tmp_var = c->value; + zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var); + ZEND_VM_NEXT_OPCODE(); + } else if ((opline->extended_value & IS_CONSTANT_RT_NS_CHECK) != 0) { + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { + zend_error_noreturn(E_ERROR, "Undefined constant '%s::%s'", Z_STRVAL(opline->op1.u.constant), Z_STRVAL(opline->op2.u.constant)); + } else if (!zend_get_constant(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) { + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", + Z_STRVAL(opline->op2.u.constant), + Z_STRVAL(opline->op2.u.constant)); + EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant; + zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var); + } + ZEND_VM_NEXT_OPCODE(); + } + /* no constant found. try a constant in class */ ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC); if (!ce) { zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL(opline->op2.u.constant)); @@ -12117,9 +12199,16 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* try a function in namespace */ + zend_op *op_data = opline+1; ZEND_VM_INC_OPCODE(); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); + } + /* no function found. try a static method in class */ ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC); if (!ce) { @@ -12136,7 +12225,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND } } if(IS_TMP_VAR != IS_UNUSED) { - char *function_name_strval = NULL; + char *function_name_strval; int function_name_strlen = 0; zend_free_op free_op2; @@ -12154,7 +12243,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND } } - if (function_name_strval) { + if (function_name_strlen) { if (ce->get_static_method) { EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } else { @@ -13944,9 +14033,16 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_VAR == IS_CONST && IS_VAR == IS_CONST) { + /* try a function in namespace */ + zend_op *op_data = opline+1; ZEND_VM_INC_OPCODE(); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); + } + /* no function found. try a static method in class */ ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC); if (!ce) { @@ -13963,7 +14059,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND } } if(IS_VAR != IS_UNUSED) { - char *function_name_strval = NULL; + char *function_name_strval; int function_name_strlen = 0; zend_free_op free_op2; @@ -13981,7 +14077,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND } } - if (function_name_strval) { + if (function_name_strlen) { if (ce->get_static_method) { EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } else { @@ -14864,9 +14960,16 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_VAR == IS_CONST && IS_UNUSED == IS_CONST) { + /* try a function in namespace */ + zend_op *op_data = opline+1; ZEND_VM_INC_OPCODE(); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); + } + /* no function found. try a static method in class */ ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC); if (!ce) { @@ -14883,7 +14986,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z } } if(IS_UNUSED != IS_UNUSED) { - char *function_name_strval = NULL; + char *function_name_strval; int function_name_strlen = 0; @@ -14901,7 +15004,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z } } - if (function_name_strval) { + if (function_name_strlen) { if (ce->get_static_method) { EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } else { @@ -16378,9 +16481,16 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_ zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_VAR == IS_CONST && IS_CV == IS_CONST) { + /* try a function in namespace */ + zend_op *op_data = opline+1; ZEND_VM_INC_OPCODE(); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); + } + /* no function found. try a static method in class */ ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC); if (!ce) { @@ -16397,7 +16507,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_ } } if(IS_CV != IS_UNUSED) { - char *function_name_strval = NULL; + char *function_name_strval; int function_name_strlen = 0; @@ -16415,7 +16525,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_ } } - if (function_name_strval) { + if (function_name_strlen) { if (ce->get_static_method) { EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } else { @@ -17740,31 +17850,46 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC zend_op *opline = EX(opline); if (IS_UNUSED == IS_UNUSED) { - /* namespaced constant */ - if (!zend_get_constant_ex(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var, NULL, opline->extended_value TSRMLS_CC)) { - if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { - char *actual = (char *)zend_memrchr(Z_STRVAL(opline->op2.u.constant), '\\', Z_STRLEN(opline->op2.u.constant)); - if(!actual) { - actual = Z_STRVAL(opline->op2.u.constant); - } else { - actual++; - } - /* non-qualified constant - allow text substitution */ - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); - ZVAL_STRINGL(&EX_T(opline->result.u.var).tmp_var, actual, Z_STRLEN(opline->op2.u.constant)-(actual - Z_STRVAL(opline->op2.u.constant)), 1); - } else { - zend_error_noreturn(E_ERROR, "Undefined constant '%s'", - Z_STRVAL(opline->op2.u.constant), Z_STRVAL(opline->op2.u.constant)); - } + if (!zend_get_constant(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) { + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { + zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL(opline->op2.u.constant)); + } + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", + Z_STRVAL(opline->op2.u.constant), + Z_STRVAL(opline->op2.u.constant)); + EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant; + zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var); } ZEND_VM_NEXT_OPCODE(); } else { - /* class constant */ zend_class_entry *ce; zval **value; if (IS_UNUSED == IS_CONST) { + zend_op *op_data = opline + 1; + zend_constant *c; + + ZEND_VM_INC_OPCODE(); + + /* try a constant in namespace */ + if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &c)==SUCCESS) { + EX_T(opline->result.u.var).tmp_var = c->value; + zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var); + ZEND_VM_NEXT_OPCODE(); + } else if ((opline->extended_value & IS_CONSTANT_RT_NS_CHECK) != 0) { + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { + zend_error_noreturn(E_ERROR, "Undefined constant '%s::%s'", Z_STRVAL(opline->op1.u.constant), Z_STRVAL(opline->op2.u.constant)); + } else if (!zend_get_constant(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) { + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", + Z_STRVAL(opline->op2.u.constant), + Z_STRVAL(opline->op2.u.constant)); + EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant; + zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var); + } + ZEND_VM_NEXT_OPCODE(); + } + /* no constant found. try a constant in class */ ce = zend_fetch_class(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), opline->extended_value TSRMLS_CC); if (!ce) { zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL(opline->op2.u.constant)); |