ZEND_API void zend_vm_stack_destroy(void);
ZEND_API void* zend_vm_stack_extend(size_t size);
-static zend_always_inline zval* zend_vm_stack_alloc(size_t size)
-{
- char *top = (char*)EG(vm_stack_top);
-
- if (UNEXPECTED(size > (size_t)(((char*)EG(vm_stack_end)) - top))) {
- return (zval*)zend_vm_stack_extend(size);
- }
- EG(vm_stack_top) = (zval*)(top + size);
- return (zval*)top;
-}
-
static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame_ex(uint32_t used_stack, uint32_t call_info, zend_function *func, uint32_t num_args, zend_class_entry *called_scope, zend_object *object)
{
- zend_execute_data *call = (zend_execute_data*)zend_vm_stack_alloc(used_stack);
+ zend_execute_data *call = (zend_execute_data*)EG(vm_stack_top);
+ if (UNEXPECTED(used_stack > (size_t)(((char*)EG(vm_stack_end)) - (char*)call))) {
+ call = (zend_execute_data*)zend_vm_stack_extend(used_stack);
+ ZEND_SET_CALL_INFO(call, call_info | ZEND_CALL_ALLOCATED);
+ } else {
+ EG(vm_stack_top) = (zval*)((char*)call + used_stack);
+ ZEND_SET_CALL_INFO(call, call_info);
+ }
call->func = func;
Z_OBJ(call->This) = object;
- ZEND_SET_CALL_INFO(call, call_info);
ZEND_CALL_NUM_ARGS(call) = num_args;
call->called_scope = called_scope;
return call;
}
}
-static zend_always_inline void zend_vm_stack_free_call_frame(zend_execute_data *call)
+static zend_always_inline void zend_vm_stack_free_call_frame_ex(uint32_t call_info, zend_execute_data *call)
{
- zend_vm_stack p = EG(vm_stack);
- if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(p) == (zval*)call)) {
+ if (UNEXPECTED(call_info & ZEND_CALL_ALLOCATED)) {
+ zend_vm_stack p = EG(vm_stack);
+
zend_vm_stack prev = p->prev;
EG(vm_stack_top) = prev->top;
}
}
+static zend_always_inline void zend_vm_stack_free_call_frame(zend_execute_data *call)
+{
+ zend_vm_stack_free_call_frame_ex(ZEND_CALL_INFO(call), call);
+}
+
/* services */
ZEND_API const char *get_active_class_name(const char **space);
ZEND_API const char *get_active_function_name(void);
if (UNEXPECTED(EX(symbol_table) != NULL)) {
zend_clean_and_cache_symbol_table(EX(symbol_table));
}
- zend_vm_stack_free_extra_args(execute_data);
+ zend_vm_stack_free_extra_args_ex(call_info, execute_data);
old_execute_data = execute_data;
execute_data = EG(current_execute_data) = EX(prev_execute_data);
if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
}
EG(scope) = EX(func)->op_array.scope;
- zend_vm_stack_free_call_frame(old_execute_data);
+ zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
if (UNEXPECTED(EG(exception) != NULL)) {
const zend_op *old_opline = EX(opline);
efree_size(EX(func), sizeof(zend_op_array));
old_execute_data = execute_data;
execute_data = EG(current_execute_data) = EX(prev_execute_data);
- zend_vm_stack_free_call_frame(old_execute_data);
+ zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
zend_attach_symbol_table(execute_data);
if (UNEXPECTED(EG(exception) != NULL)) {
if (UNEXPECTED(EX(symbol_table) != NULL)) {
zend_clean_and_cache_symbol_table(EX(symbol_table));
}
- zend_vm_stack_free_extra_args(execute_data);
+ zend_vm_stack_free_extra_args_ex(call_info, execute_data);
EG(current_execute_data) = EX(prev_execute_data);
if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype);
}
EG(current_execute_data) = EX(prev_execute_data);
}
- zend_vm_stack_free_call_frame(execute_data);
+ zend_vm_stack_free_call_frame_ex(call_info, execute_data);
ZEND_VM_RETURN();
}
if (UNEXPECTED(EX(symbol_table) != NULL)) {
zend_clean_and_cache_symbol_table(EX(symbol_table));
}
- zend_vm_stack_free_extra_args(execute_data);
+ zend_vm_stack_free_extra_args_ex(call_info, execute_data);
old_execute_data = execute_data;
execute_data = EG(current_execute_data) = EX(prev_execute_data);
if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
}
EG(scope) = EX(func)->op_array.scope;
- zend_vm_stack_free_call_frame(old_execute_data);
+ zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
if (UNEXPECTED(EG(exception) != NULL)) {
const zend_op *old_opline = EX(opline);
efree_size(EX(func), sizeof(zend_op_array));
old_execute_data = execute_data;
execute_data = EG(current_execute_data) = EX(prev_execute_data);
- zend_vm_stack_free_call_frame(old_execute_data);
+ zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
zend_attach_symbol_table(execute_data);
if (UNEXPECTED(EG(exception) != NULL)) {
if (UNEXPECTED(EX(symbol_table) != NULL)) {
zend_clean_and_cache_symbol_table(EX(symbol_table));
}
- zend_vm_stack_free_extra_args(execute_data);
+ zend_vm_stack_free_extra_args_ex(call_info, execute_data);
EG(current_execute_data) = EX(prev_execute_data);
if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype);
}
EG(current_execute_data) = EX(prev_execute_data);
}
- zend_vm_stack_free_call_frame(execute_data);
+ zend_vm_stack_free_call_frame_ex(call_info, execute_data);
ZEND_VM_RETURN();
}
try_function_name:
if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
const char *colon;
-
+
if ((colon = zend_memrchr(Z_STRVAL_P(function_name), ':', Z_STRLEN_P(function_name))) != NULL &&
colon > Z_STRVAL_P(function_name) &&
*(colon-1) == ':'
zend_string *mname;
size_t cname_length = colon - Z_STRVAL_P(function_name) - 1;
size_t mname_length = Z_STRLEN_P(function_name) - cname_length - (sizeof("::") - 1);
-
+
if (!mname_length) {
zend_error(E_EXCEPTION | E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
HANDLE_EXCEPTION();
}
-
+
lcname = zend_string_init(Z_STRVAL_P(function_name), cname_length, 0);
-
+
called_scope = zend_fetch_class_by_name(lcname, NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
if (UNEXPECTED(called_scope == NULL)) {
zend_string_release(lcname);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
-
+
mname = zend_string_init(Z_STRVAL_P(function_name) + (cname_length + sizeof("::") - 1), mname_length, 0);
-
+
if (called_scope->get_static_method) {
fbc = called_scope->get_static_method(called_scope, mname);
} else {
HANDLE_EXCEPTION();
}
-
+
zend_string_release(lcname);
zend_string_release(mname);
-
+
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
zend_error(E_DEPRECATED,
called_scope = NULL;
object = NULL;
}
+
} else if (IS_CONST != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
try_function_name:
if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
const char *colon;
-
+
if ((colon = zend_memrchr(Z_STRVAL_P(function_name), ':', Z_STRLEN_P(function_name))) != NULL &&
colon > Z_STRVAL_P(function_name) &&
*(colon-1) == ':'
zend_string *mname;
size_t cname_length = colon - Z_STRVAL_P(function_name) - 1;
size_t mname_length = Z_STRLEN_P(function_name) - cname_length - (sizeof("::") - 1);
-
+
if (!mname_length) {
zend_error(E_EXCEPTION | E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
HANDLE_EXCEPTION();
}
-
+
lcname = zend_string_init(Z_STRVAL_P(function_name), cname_length, 0);
-
+
called_scope = zend_fetch_class_by_name(lcname, NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
if (UNEXPECTED(called_scope == NULL)) {
zend_string_release(lcname);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
-
+
mname = zend_string_init(Z_STRVAL_P(function_name) + (cname_length + sizeof("::") - 1), mname_length, 0);
-
+
if (called_scope->get_static_method) {
fbc = called_scope->get_static_method(called_scope, mname);
} else {
HANDLE_EXCEPTION();
}
-
+
zend_string_release(lcname);
zend_string_release(mname);
-
+
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
zend_error(E_DEPRECATED,
called_scope = NULL;
object = NULL;
}
+
} else if (IS_CV != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
try_function_name:
if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
const char *colon;
-
+
if ((colon = zend_memrchr(Z_STRVAL_P(function_name), ':', Z_STRLEN_P(function_name))) != NULL &&
colon > Z_STRVAL_P(function_name) &&
*(colon-1) == ':'
zend_string *mname;
size_t cname_length = colon - Z_STRVAL_P(function_name) - 1;
size_t mname_length = Z_STRLEN_P(function_name) - cname_length - (sizeof("::") - 1);
-
+
if (!mname_length) {
zend_error(E_EXCEPTION | E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
zval_ptr_dtor_nogc(free_op2);
HANDLE_EXCEPTION();
}
-
+
lcname = zend_string_init(Z_STRVAL_P(function_name), cname_length, 0);
-
+
called_scope = zend_fetch_class_by_name(lcname, NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
if (UNEXPECTED(called_scope == NULL)) {
zend_string_release(lcname);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
-
+
mname = zend_string_init(Z_STRVAL_P(function_name) + (cname_length + sizeof("::") - 1), mname_length, 0);
-
+
if (called_scope->get_static_method) {
fbc = called_scope->get_static_method(called_scope, mname);
} else {
zval_ptr_dtor_nogc(free_op2);
HANDLE_EXCEPTION();
}
-
+
zend_string_release(lcname);
zend_string_release(mname);
-
+
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
zend_error(E_DEPRECATED,