diff options
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r-- | Zend/zend_execute.c | 158 |
1 files changed, 41 insertions, 117 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index d3ca248de8..7c8621fe64 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -871,62 +871,28 @@ static zend_always_inline int zend_verify_arg_type(zend_function *zf, uint32_t a return 1; } -static zend_always_inline int zend_verify_missing_arg_type(zend_function *zf, uint32_t arg_num, void **cache_slot) -{ - zend_arg_info *cur_arg_info; - char *need_msg; - zend_class_entry *ce; - - if (EXPECTED(arg_num <= zf->common.num_args)) { - cur_arg_info = &zf->common.arg_info[arg_num-1]; - } else if (UNEXPECTED(zf->common.fn_flags & ZEND_ACC_VARIADIC)) { - cur_arg_info = &zf->common.arg_info[zf->common.num_args]; +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(zend_execute_data *execute_data) +{ + zend_execute_data *ptr = EX(prev_execute_data); + + if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) { + zend_throw_error(NULL, "Too few arguments to function %s%s%s(), %d passed in %s on line %d and %s %d expected", + EX(func)->common.scope ? ZSTR_VAL(EX(func)->common.scope->name) : "", + EX(func)->common.scope ? "::" : "", + ZSTR_VAL(EX(func)->common.function_name), + EX_NUM_ARGS(), + ZSTR_VAL(ptr->func->op_array.filename), + ptr->opline->lineno, + EX(func)->common.required_num_args == EX(func)->common.num_args ? "exactly" : "at least", + EX(func)->common.required_num_args); } else { - return 1; - } - - if (cur_arg_info->type_hint) { - if (cur_arg_info->class_name) { - if (EXPECTED(*cache_slot)) { - ce = (zend_class_entry*)*cache_slot; - } else { - ce = zend_verify_arg_class_kind(cur_arg_info); - if (UNEXPECTED(!ce)) { - zend_verify_arg_error(zf, arg_num, "be an instance of ", ZSTR_VAL(cur_arg_info->class_name), "none", ""); - return 0; - } - *cache_slot = (void*)ce; - } - need_msg = - (ce->ce_flags & ZEND_ACC_INTERFACE) ? - "implement interface " : "be an instance of "; - zend_verify_arg_error(zf, arg_num, need_msg, ZSTR_VAL(ce->name), "none", ""); - } else if (cur_arg_info->type_hint == IS_CALLABLE) { - zend_verify_arg_error(zf, arg_num, "be callable", "", "none", ""); - } else if (cur_arg_info->type_hint == IS_ITERABLE) { - zend_verify_arg_error(zf, arg_num, "be iterable", "", "none", ""); - } else { - zend_verify_arg_error(zf, arg_num, "be of the type ", zend_get_type_by_const(cur_arg_info->type_hint), "none", ""); - } - return 0; - } - return 1; -} - -static ZEND_COLD void zend_verify_missing_arg(zend_execute_data *execute_data, uint32_t arg_num, void **cache_slot) -{ - if (EXPECTED(!(EX(func)->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) || - UNEXPECTED(zend_verify_missing_arg_type(EX(func), arg_num, cache_slot))) { - const char *class_name = EX(func)->common.scope ? ZSTR_VAL(EX(func)->common.scope->name) : ""; - const char *space = EX(func)->common.scope ? "::" : ""; - const char *func_name = EX(func)->common.function_name ? ZSTR_VAL(EX(func)->common.function_name) : "main"; - zend_execute_data *ptr = EX(prev_execute_data); - - if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) { - zend_error(E_WARNING, "Missing argument %u for %s%s%s(), called in %s on line %d and defined", arg_num, class_name, space, func_name, ZSTR_VAL(ptr->func->op_array.filename), ptr->opline->lineno); - } else { - zend_error(E_WARNING, "Missing argument %u for %s%s%s()", arg_num, class_name, space, func_name); - } + zend_throw_error(NULL, "Too few arguments to function %s%s%s(), %d passed and %s %d expected", + EX(func)->common.scope ? ZSTR_VAL(EX(func)->common.scope->name) : "", + EX(func)->common.scope ? "::" : "", + ZSTR_VAL(EX(func)->common.function_name), + EX_NUM_ARGS(), + EX(func)->common.required_num_args == EX(func)->common.num_args ? "exactly" : "at least", + EX(func)->common.required_num_args); } } @@ -1662,7 +1628,7 @@ str_index: hval = zend_dval_to_lval(Z_DVAL_P(dim)); goto num_index; case IS_RESOURCE: - zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(dim), Z_RES_HANDLE_P(dim)); + zend_error(E_NOTICE, "Resource ID#%d used as offset, casting to integer (%d)", Z_RES_HANDLE_P(dim), Z_RES_HANDLE_P(dim)); hval = Z_RES_HANDLE_P(dim); goto num_index; case IS_FALSE: @@ -1733,15 +1699,7 @@ fetch_from_array: goto try_array; } } - if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (type != BP_VAR_UNSET && UNEXPECTED(Z_STRLEN_P(container) == 0)) { - zval_ptr_dtor_nogc(container); -convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto fetch_from_array; - } - + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (dim == NULL) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { @@ -1801,7 +1759,9 @@ convert_to_array: } if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { if (type != BP_VAR_UNSET) { - goto convert_to_array; + ZVAL_NEW_ARR(container); + zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + goto fetch_from_array; } else { /* for read-mode only */ ZVAL_NULL(result); @@ -1894,7 +1854,7 @@ try_string_offset: if (UNEXPECTED(Z_STRLEN_P(container) < (size_t)((offset < 0) ? -offset : (offset + 1)))) { if (type != BP_VAR_IS) { - zend_error(E_NOTICE, "Uninitialized string offset: %pd", offset); + zend_error(E_NOTICE, "Uninitialized string offset: " ZEND_LONG_FMT, offset); ZVAL_EMPTY_STRING(result); } else { ZVAL_NULL(result); @@ -1979,11 +1939,6 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c { if (container_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { do { - if (container_op_type == IS_VAR && UNEXPECTED(Z_ISERROR_P(container))) { - ZVAL_ERROR(result); - return; - } - if (Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { @@ -1998,7 +1953,9 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c zval_ptr_dtor_nogc(container); object_init(container); } else { - zend_error(E_WARNING, "Attempt to modify property of non-object"); + if (container_op_type != IS_VAR || EXPECTED(!Z_ISERROR_P(container))) { + zend_error(E_WARNING, "Attempt to modify property of non-object"); + } ZVAL_ERROR(result); return; } @@ -2034,6 +1991,7 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c zval *ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot); if (NULL == ptr) { if (EXPECTED(Z_OBJ_HT_P(container)->read_property)) { +use_read_property: ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result); if (ptr != result) { ZVAL_INDIRECT(result, ptr); @@ -2048,12 +2006,7 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c ZVAL_INDIRECT(result, ptr); } } else if (EXPECTED(Z_OBJ_HT_P(container)->read_property)) { - zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result); - if (ptr != result) { - ZVAL_INDIRECT(result, ptr); - } else if (UNEXPECTED(Z_ISREF_P(ptr) && Z_REFCOUNT_P(ptr) == 1)) { - ZVAL_UNREF(ptr); - } + goto use_read_property; } else { zend_error(E_WARNING, "This object doesn't support property references"); ZVAL_ERROR(result); @@ -2137,15 +2090,15 @@ void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */ } /* }}} */ -static zend_never_inline ZEND_COLD ZEND_NORETURN void ZEND_FASTCALL zend_interrupt(void) /* {{{ */ -{ - zend_timeout(0); -} -/* }}} */ - #define ZEND_VM_INTERRUPT_CHECK() do { \ - if (UNEXPECTED(EG(timed_out))) { \ - zend_interrupt(); \ + if (UNEXPECTED(EG(vm_interrupt))) { \ + ZEND_VM_INTERRUPT(); \ + } \ + } while (0) + +#define ZEND_VM_LOOP_INTERRUPT_CHECK() do { \ + if (UNEXPECTED(EG(vm_interrupt))) { \ + ZEND_VM_LOOP_INTERRUPT(); \ } \ } while (0) @@ -2169,7 +2122,7 @@ static zend_never_inline ZEND_COLD ZEND_NORETURN void ZEND_FASTCALL zend_interru * +----------------------------------------+ */ -static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, int check_this) /* {{{ */ +static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */ { uint32_t first_extra_arg, num_args; ZEND_ASSERT(EX(func) == (zend_function*)op_array); @@ -2227,11 +2180,6 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu } while (var != end); } - if (check_this && op_array->this_var != (uint32_t)-1 && EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { - ZVAL_OBJ(EX_VAR(op_array->this_var), Z_OBJ(EX(This))); - GC_REFCOUNT(Z_OBJ(EX(This)))++; - } - EX_LOAD_RUN_TIME_CACHE(op_array); EX_LOAD_LITERALS(op_array); @@ -2255,13 +2203,6 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu EX(call) = NULL; EX(return_value) = return_value; - if (UNEXPECTED(op_array->this_var != (uint32_t)-1) && EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { - GC_REFCOUNT(Z_OBJ(EX(This)))++; - if (!zend_hash_add(EX(symbol_table), CG(known_strings)[ZEND_STR_THIS], &EX(This))) { - GC_REFCOUNT(Z_OBJ(EX(This)))--; - } - } - zend_attach_symbol_table(execute_data); if (!op_array->run_time_cache) { @@ -2284,13 +2225,6 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da EX(return_value) = return_value; if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { - if (UNEXPECTED(op_array->this_var != (uint32_t)-1) && EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { - GC_REFCOUNT(Z_OBJ(EX(This)))++; - if (!zend_hash_add(EX(symbol_table), CG(known_strings)[ZEND_STR_THIS], &EX(This))) { - GC_REFCOUNT(Z_OBJ(EX(This)))--; - } - } - zend_attach_symbol_table(execute_data); } else { uint32_t first_extra_arg, num_args; @@ -2343,11 +2277,6 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da var++; } while (var != end); } - - if (op_array->this_var != (uint32_t)-1 && EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { - ZVAL_OBJ(EX_VAR(op_array->this_var), Z_OBJ(EX(This))); - GC_REFCOUNT(Z_OBJ(EX(This)))++; - } } if (!op_array->run_time_cache) { @@ -3133,11 +3062,6 @@ ZEND_API int ZEND_FASTCALL zend_check_arg_type(zend_function *zf, uint32_t arg_n return zend_verify_arg_type(zf, arg_num, arg, default_value, cache_slot); } -ZEND_API void ZEND_FASTCALL zend_check_missing_arg(zend_execute_data *execute_data, uint32_t arg_num, void **cache_slot) -{ - zend_verify_missing_arg(execute_data, arg_num, cache_slot); -} - /* * Local variables: * tab-width: 4 |