diff options
Diffstat (limited to 'Zend/zend_vm_execute.h')
| -rw-r--r-- | Zend/zend_vm_execute.h | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 63db4987d6..fd726eb880 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1246,6 +1246,67 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); + } else if (IS_CONST != IS_CONST && + EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && + zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { + zend_class_entry *ce; + zval **method = NULL; + zval **obj = NULL; + + zend_hash_index_find(Z_ARRVAL_P(function_name), 0, (void **) &obj); + zend_hash_index_find(Z_ARRVAL_P(function_name), 1, (void **) &method); + + if (Z_TYPE_PP(obj) != IS_STRING && Z_TYPE_PP(obj) != IS_OBJECT) { + zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object"); + } + + if (Z_TYPE_PP(method) != IS_STRING) { + zend_error_noreturn(E_ERROR, "Second array member is not a valid method"); + } + + if (Z_TYPE_PP(obj) == IS_STRING) { + ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC); + if (UNEXPECTED(ce == NULL)) { + zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj)); + } + EX(called_scope) = ce; + EX(object) = NULL; + + if (ce->get_static_method) { + EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC); + } else { + EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC); + } + } else { + EX(object) = *obj; + ce = EX(called_scope) = Z_OBJCE_PP(obj); + + EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC); + if (UNEXPECTED(EX(fbc) == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method)); + } + + if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) { + EX(object) = NULL; + } else { + if (!PZVAL_IS_REF(EX(object))) { + Z_ADDREF_P(EX(object)); /* For $this pointer */ + } else { + zval *this_ptr; + ALLOC_ZVAL(this_ptr); + INIT_PZVAL_COPY(this_ptr, EX(object)); + zval_copy_ctor(this_ptr); + EX(object) = this_ptr; + } + } + } + + if (UNEXPECTED(EX(fbc) == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } else { zend_error_noreturn(E_ERROR, "Function name must be a string"); } @@ -1486,6 +1547,67 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); + } else if (IS_TMP_VAR != IS_CONST && + EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && + zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { + zend_class_entry *ce; + zval **method = NULL; + zval **obj = NULL; + + zend_hash_index_find(Z_ARRVAL_P(function_name), 0, (void **) &obj); + zend_hash_index_find(Z_ARRVAL_P(function_name), 1, (void **) &method); + + if (Z_TYPE_PP(obj) != IS_STRING && Z_TYPE_PP(obj) != IS_OBJECT) { + zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object"); + } + + if (Z_TYPE_PP(method) != IS_STRING) { + zend_error_noreturn(E_ERROR, "Second array member is not a valid method"); + } + + if (Z_TYPE_PP(obj) == IS_STRING) { + ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC); + if (UNEXPECTED(ce == NULL)) { + zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj)); + } + EX(called_scope) = ce; + EX(object) = NULL; + + if (ce->get_static_method) { + EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC); + } else { + EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC); + } + } else { + EX(object) = *obj; + ce = EX(called_scope) = Z_OBJCE_PP(obj); + + EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC); + if (UNEXPECTED(EX(fbc) == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method)); + } + + if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) { + EX(object) = NULL; + } else { + if (!PZVAL_IS_REF(EX(object))) { + Z_ADDREF_P(EX(object)); /* For $this pointer */ + } else { + zval *this_ptr; + ALLOC_ZVAL(this_ptr); + INIT_PZVAL_COPY(this_ptr, EX(object)); + zval_copy_ctor(this_ptr); + EX(object) = this_ptr; + } + } + } + + if (UNEXPECTED(EX(fbc) == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); + } + zval_dtor(free_op2.var); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } else { zend_error_noreturn(E_ERROR, "Function name must be a string"); } @@ -1588,6 +1710,67 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); + } else if (IS_VAR != IS_CONST && + EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && + zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { + zend_class_entry *ce; + zval **method = NULL; + zval **obj = NULL; + + zend_hash_index_find(Z_ARRVAL_P(function_name), 0, (void **) &obj); + zend_hash_index_find(Z_ARRVAL_P(function_name), 1, (void **) &method); + + if (Z_TYPE_PP(obj) != IS_STRING && Z_TYPE_PP(obj) != IS_OBJECT) { + zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object"); + } + + if (Z_TYPE_PP(method) != IS_STRING) { + zend_error_noreturn(E_ERROR, "Second array member is not a valid method"); + } + + if (Z_TYPE_PP(obj) == IS_STRING) { + ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC); + if (UNEXPECTED(ce == NULL)) { + zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj)); + } + EX(called_scope) = ce; + EX(object) = NULL; + + if (ce->get_static_method) { + EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC); + } else { + EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC); + } + } else { + EX(object) = *obj; + ce = EX(called_scope) = Z_OBJCE_PP(obj); + + EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC); + if (UNEXPECTED(EX(fbc) == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method)); + } + + if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) { + EX(object) = NULL; + } else { + if (!PZVAL_IS_REF(EX(object))) { + Z_ADDREF_P(EX(object)); /* For $this pointer */ + } else { + zval *this_ptr; + ALLOC_ZVAL(this_ptr); + INIT_PZVAL_COPY(this_ptr, EX(object)); + zval_copy_ctor(this_ptr); + EX(object) = this_ptr; + } + } + } + + if (UNEXPECTED(EX(fbc) == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); + } + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } else { zend_error_noreturn(E_ERROR, "Function name must be a string"); } @@ -1723,6 +1906,67 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); + } else if (IS_CV != IS_CONST && + EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && + zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { + zend_class_entry *ce; + zval **method = NULL; + zval **obj = NULL; + + zend_hash_index_find(Z_ARRVAL_P(function_name), 0, (void **) &obj); + zend_hash_index_find(Z_ARRVAL_P(function_name), 1, (void **) &method); + + if (Z_TYPE_PP(obj) != IS_STRING && Z_TYPE_PP(obj) != IS_OBJECT) { + zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object"); + } + + if (Z_TYPE_PP(method) != IS_STRING) { + zend_error_noreturn(E_ERROR, "Second array member is not a valid method"); + } + + if (Z_TYPE_PP(obj) == IS_STRING) { + ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC); + if (UNEXPECTED(ce == NULL)) { + zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj)); + } + EX(called_scope) = ce; + EX(object) = NULL; + + if (ce->get_static_method) { + EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC); + } else { + EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC); + } + } else { + EX(object) = *obj; + ce = EX(called_scope) = Z_OBJCE_PP(obj); + + EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC); + if (UNEXPECTED(EX(fbc) == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method)); + } + + if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) { + EX(object) = NULL; + } else { + if (!PZVAL_IS_REF(EX(object))) { + Z_ADDREF_P(EX(object)); /* For $this pointer */ + } else { + zval *this_ptr; + ALLOC_ZVAL(this_ptr); + INIT_PZVAL_COPY(this_ptr, EX(object)); + zval_copy_ctor(this_ptr); + EX(object) = this_ptr; + } + } + } + + if (UNEXPECTED(EX(fbc) == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } else { zend_error_noreturn(E_ERROR, "Function name must be a string"); } |
