mirror of
https://github.com/php/php-src.git
synced 2024-12-03 06:44:07 +08:00
Merge branch 'master' of git.php.net:php-src
This commit is contained in:
commit
0a5bbbdc92
@ -726,7 +726,7 @@ ZEND_API zend_op_array *compile_filename(int type, zval *filename);
|
||||
ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...);
|
||||
ZEND_API int open_file_for_scanning(zend_file_handle *file_handle);
|
||||
ZEND_API void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size);
|
||||
ZEND_API void destroy_op_array(zend_op_array *op_array);
|
||||
ZEND_API zend_bool destroy_op_array(zend_op_array *op_array);
|
||||
ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle);
|
||||
ZEND_API void zend_cleanup_user_class_data(zend_class_entry *ce);
|
||||
ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce);
|
||||
|
@ -335,7 +335,7 @@ void zend_class_add_ref(zval *zv)
|
||||
ce->refcount++;
|
||||
}
|
||||
|
||||
ZEND_API void destroy_op_array(zend_op_array *op_array)
|
||||
ZEND_API zend_bool destroy_op_array(zend_op_array *op_array)
|
||||
{
|
||||
zval *literal = op_array->literals;
|
||||
zval *end;
|
||||
@ -352,8 +352,12 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
|
||||
efree(op_array->run_time_cache);
|
||||
}
|
||||
|
||||
if (!op_array->refcount || --(*op_array->refcount)>0) {
|
||||
return;
|
||||
if (!op_array->refcount) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (--(*op_array->refcount) > 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
efree_size(op_array->refcount, sizeof(*(op_array->refcount)));
|
||||
@ -414,6 +418,8 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
|
||||
}
|
||||
efree(arg_info);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void init_op(zend_op *op)
|
||||
|
@ -2364,8 +2364,9 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
|
||||
ZEND_VM_LEAVE();
|
||||
} else if (ZEND_CALL_KIND_EX(call_info) == ZEND_CALL_NESTED_CODE) {
|
||||
zend_detach_symbol_table(execute_data);
|
||||
destroy_op_array(&EX(func)->op_array);
|
||||
efree_size(EX(func), sizeof(zend_op_array));
|
||||
if (EXPECTED(destroy_op_array(&EX(func)->op_array) != 0)) {
|
||||
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_ex(call_info, old_execute_data);
|
||||
@ -5439,7 +5440,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY)
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
i_init_code_execute_data(call, new_op_array, return_value);
|
||||
i_init_code_execute_data(call, new_op_array, return_value);
|
||||
if (EXPECTED(zend_execute_ex == execute_ex)) {
|
||||
ZEND_VM_ENTER();
|
||||
} else {
|
||||
@ -5448,8 +5449,9 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY)
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
}
|
||||
|
||||
destroy_op_array(new_op_array);
|
||||
efree_size(new_op_array, sizeof(zend_op_array));
|
||||
if (EXPECTED(destroy_op_array(new_op_array) != 0)) {
|
||||
efree_size(new_op_array, sizeof(zend_op_array));
|
||||
}
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
zend_throw_exception_internal(NULL);
|
||||
HANDLE_EXCEPTION();
|
||||
|
@ -503,8 +503,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_
|
||||
ZEND_VM_LEAVE();
|
||||
} else if (ZEND_CALL_KIND_EX(call_info) == ZEND_CALL_NESTED_CODE) {
|
||||
zend_detach_symbol_table(execute_data);
|
||||
destroy_op_array(&EX(func)->op_array);
|
||||
efree_size(EX(func), sizeof(zend_op_array));
|
||||
if (EXPECTED(destroy_op_array(&EX(func)->op_array) != 0)) {
|
||||
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_ex(call_info, old_execute_data);
|
||||
@ -3642,7 +3643,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
i_init_code_execute_data(call, new_op_array, return_value);
|
||||
i_init_code_execute_data(call, new_op_array, return_value);
|
||||
if (EXPECTED(zend_execute_ex == execute_ex)) {
|
||||
ZEND_VM_ENTER();
|
||||
} else {
|
||||
@ -3651,8 +3652,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
}
|
||||
|
||||
destroy_op_array(new_op_array);
|
||||
efree_size(new_op_array, sizeof(zend_op_array));
|
||||
if (EXPECTED(destroy_op_array(new_op_array) != 0)) {
|
||||
efree_size(new_op_array, sizeof(zend_op_array));
|
||||
}
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
zend_throw_exception_internal(NULL);
|
||||
HANDLE_EXCEPTION();
|
||||
@ -29006,7 +29008,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
i_init_code_execute_data(call, new_op_array, return_value);
|
||||
i_init_code_execute_data(call, new_op_array, return_value);
|
||||
if (EXPECTED(zend_execute_ex == execute_ex)) {
|
||||
ZEND_VM_ENTER();
|
||||
} else {
|
||||
@ -29015,8 +29017,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
}
|
||||
|
||||
destroy_op_array(new_op_array);
|
||||
efree_size(new_op_array, sizeof(zend_op_array));
|
||||
if (EXPECTED(destroy_op_array(new_op_array) != 0)) {
|
||||
efree_size(new_op_array, sizeof(zend_op_array));
|
||||
}
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
zend_throw_exception_internal(NULL);
|
||||
HANDLE_EXCEPTION();
|
||||
@ -40417,7 +40420,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HA
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
i_init_code_execute_data(call, new_op_array, return_value);
|
||||
i_init_code_execute_data(call, new_op_array, return_value);
|
||||
if (EXPECTED(zend_execute_ex == execute_ex)) {
|
||||
ZEND_VM_ENTER();
|
||||
} else {
|
||||
@ -40426,8 +40429,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HA
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
}
|
||||
|
||||
destroy_op_array(new_op_array);
|
||||
efree_size(new_op_array, sizeof(zend_op_array));
|
||||
if (EXPECTED(destroy_op_array(new_op_array) != 0)) {
|
||||
efree_size(new_op_array, sizeof(zend_op_array));
|
||||
}
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
zend_throw_exception_internal(NULL);
|
||||
HANDLE_EXCEPTION();
|
||||
|
@ -480,6 +480,114 @@ static void phpdbg_oplog_fill_executable(zend_op_array *op_array, HashTable *ins
|
||||
}
|
||||
}
|
||||
|
||||
static inline HashTable* phpdbg_add_empty_array(HashTable *ht, zend_string *name) {
|
||||
zval *ht_zv = zend_hash_find(ht, name);
|
||||
if (!ht_zv) {
|
||||
zval zv;
|
||||
array_init(&zv);
|
||||
ht_zv = zend_hash_add_new(ht, name, &zv);
|
||||
}
|
||||
return Z_ARR_P(ht_zv);
|
||||
}
|
||||
|
||||
/* {{{ proto void phpdbg_end_oplog() */
|
||||
static PHP_FUNCTION(phpdbg_get_executable)
|
||||
{
|
||||
HashTable *options = NULL;
|
||||
zval *option_buffer;
|
||||
zend_bool by_function = 0;
|
||||
zend_bool by_opcode = 0;
|
||||
HashTable *insert_ht;
|
||||
|
||||
zend_function *func;
|
||||
zend_class_entry *ce;
|
||||
zend_string *name;
|
||||
HashTable *files = &PHPDBG_G(file_sources);
|
||||
HashTable files_tmp;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|H", &options) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("functions")))) {
|
||||
by_function = zend_is_true(option_buffer);
|
||||
}
|
||||
|
||||
if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("opcodes")))) {
|
||||
if (by_function) {
|
||||
by_opcode = zend_is_true(option_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("files")))) {
|
||||
ZVAL_DEREF(option_buffer);
|
||||
if (Z_TYPE_P(option_buffer) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(option_buffer)) > 0) {
|
||||
zval *filename;
|
||||
|
||||
files = &files_tmp;
|
||||
zend_hash_init(files, 0, NULL, NULL, 0);
|
||||
|
||||
ZEND_HASH_FOREACH_VAL(Z_ARR_P(option_buffer), filename) {
|
||||
zend_hash_add_empty_element(files, zval_get_string(filename));
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
} else {
|
||||
GC_REFCOUNT(files)++;
|
||||
}
|
||||
} else {
|
||||
GC_REFCOUNT(files)++;
|
||||
}
|
||||
|
||||
array_init(return_value);
|
||||
|
||||
ZEND_HASH_FOREACH_STR_KEY_PTR(EG(function_table), name, func) {
|
||||
if (func->type == ZEND_USER_FUNCTION) {
|
||||
if (zend_hash_exists(files, func->op_array.filename)) {
|
||||
insert_ht = phpdbg_add_empty_array(Z_ARR_P(return_value), func->op_array.filename);
|
||||
|
||||
if (by_function) {
|
||||
insert_ht = phpdbg_add_empty_array(insert_ht, name);
|
||||
}
|
||||
|
||||
phpdbg_oplog_fill_executable(&func->op_array, insert_ht, by_opcode);
|
||||
}
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), name, ce) {
|
||||
if (ce->type == ZEND_USER_CLASS) {
|
||||
if (zend_hash_exists(files, ce->info.user.filename)) {
|
||||
ZEND_HASH_FOREACH_PTR(&ce->function_table, func) {
|
||||
if (func->type == ZEND_USER_FUNCTION) {
|
||||
insert_ht = phpdbg_add_empty_array(Z_ARR_P(return_value), func->op_array.filename);
|
||||
|
||||
if (by_function) {
|
||||
zend_string *fn_name = strpprintf(ZSTR_LEN(name) + ZSTR_LEN(func->op_array.function_name) + 2, "%.*s::%.*s", ZSTR_LEN(name), ZSTR_VAL(name), ZSTR_LEN(func->op_array.function_name), ZSTR_VAL(func->op_array.function_name));
|
||||
insert_ht = phpdbg_add_empty_array(insert_ht, fn_name);
|
||||
zend_string_release(fn_name);
|
||||
}
|
||||
|
||||
phpdbg_oplog_fill_executable(&func->op_array, insert_ht, by_opcode);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
ZEND_HASH_FOREACH_STR_KEY(files, name) {
|
||||
phpdbg_file_source *source = zend_hash_find_ptr(&PHPDBG_G(file_sources), name);
|
||||
if (source) {
|
||||
phpdbg_oplog_fill_executable(
|
||||
source->op_array,
|
||||
phpdbg_add_empty_array(Z_ARR_P(return_value), source->op_array->filename),
|
||||
by_opcode);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
if (!--GC_REFCOUNT(files)) {
|
||||
zend_hash_destroy(files);
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ proto void phpdbg_end_oplog() */
|
||||
static PHP_FUNCTION(phpdbg_end_oplog)
|
||||
{
|
||||
@ -490,7 +598,6 @@ static PHP_FUNCTION(phpdbg_end_oplog)
|
||||
zval *option_buffer;
|
||||
zend_bool by_function = 0;
|
||||
zend_bool by_opcode = 0;
|
||||
zend_bool show_unexecuted = 0;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|H", &options) == FAILURE) {
|
||||
return;
|
||||
@ -517,18 +624,13 @@ static PHP_FUNCTION(phpdbg_end_oplog)
|
||||
}
|
||||
}
|
||||
|
||||
if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("show_unexecuted")))) {
|
||||
show_unexecuted = zend_is_true(option_buffer);
|
||||
}
|
||||
|
||||
array_init(return_value);
|
||||
|
||||
{
|
||||
zend_string *last_file = NULL;
|
||||
zval *file_buf;
|
||||
HashTable *file_ht;
|
||||
zend_string *last_function = (void *)~(uintptr_t)0;
|
||||
zend_class_entry *last_scope = NULL;
|
||||
zval *fn_buf;
|
||||
|
||||
HashTable *insert_ht;
|
||||
zend_long insert_idx;
|
||||
@ -540,23 +642,13 @@ static PHP_FUNCTION(phpdbg_end_oplog)
|
||||
|
||||
if (op_array->filename != last_file) {
|
||||
last_file = op_array->filename;
|
||||
file_buf = zend_hash_find(Z_ARR_P(return_value), last_file);
|
||||
if (!file_buf) {
|
||||
zval ht;
|
||||
array_init(&ht);
|
||||
file_buf = zend_hash_add_new(Z_ARR_P(return_value), last_file, &ht);
|
||||
|
||||
if (show_unexecuted) {
|
||||
phpdbg_oplog_fill_executable(op_array, Z_ARR_P(file_buf), by_opcode);
|
||||
}
|
||||
}
|
||||
insert_ht = Z_ARR_P(file_buf);
|
||||
file_ht = insert_ht = phpdbg_add_empty_array(Z_ARR_P(return_value), last_file);
|
||||
}
|
||||
|
||||
if (by_function) {
|
||||
if (op_array->function_name == NULL) {
|
||||
if (last_function != NULL) {
|
||||
insert_ht = Z_ARR_P(file_buf);
|
||||
insert_ht = file_ht;
|
||||
}
|
||||
last_function = NULL;
|
||||
} else if (op_array->function_name != last_function || op_array->scope != last_scope) {
|
||||
@ -568,17 +660,8 @@ static PHP_FUNCTION(phpdbg_end_oplog)
|
||||
} else {
|
||||
fn_name = strpprintf(ZSTR_LEN(last_function) + ZSTR_LEN(last_scope->name) + 2, "%.*s::%.*s", ZSTR_LEN(last_scope->name), ZSTR_VAL(last_scope->name), ZSTR_LEN(last_function), ZSTR_VAL(last_function));
|
||||
}
|
||||
fn_buf = zend_hash_find(Z_ARR_P(return_value), fn_name);
|
||||
if (!fn_buf) {
|
||||
zval ht;
|
||||
array_init(&ht);
|
||||
fn_buf = zend_hash_add_new(Z_ARR_P(return_value), fn_name, &ht);
|
||||
|
||||
if (show_unexecuted) {
|
||||
phpdbg_oplog_fill_executable(op_array, Z_ARR_P(fn_buf), by_opcode);
|
||||
}
|
||||
}
|
||||
insert_ht = Z_ARR_P(fn_buf);
|
||||
insert_ht = phpdbg_add_empty_array(Z_ARR_P(return_value), fn_name);
|
||||
zend_string_release(fn_name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -642,6 +725,11 @@ ZEND_BEGIN_ARG_INFO_EX(phpdbg_start_oplog_arginfo, 0, 0, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(phpdbg_end_oplog_arginfo, 0, 0, 0)
|
||||
ZEND_ARG_INFO(0, options)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(phpdbg_get_executable_arginfo, 0, 0, 0)
|
||||
ZEND_ARG_INFO(0, options)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
zend_function_entry phpdbg_user_functions[] = {
|
||||
@ -655,6 +743,7 @@ zend_function_entry phpdbg_user_functions[] = {
|
||||
PHP_FE(phpdbg_prompt, phpdbg_prompt_arginfo)
|
||||
PHP_FE(phpdbg_start_oplog, phpdbg_start_oplog_arginfo)
|
||||
PHP_FE(phpdbg_end_oplog, phpdbg_end_oplog_arginfo)
|
||||
PHP_FE(phpdbg_get_executable, phpdbg_get_executable_arginfo)
|
||||
#ifdef PHP_FE_END
|
||||
PHP_FE_END
|
||||
#else
|
||||
|
@ -288,6 +288,14 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
|
||||
fake.opened_path = NULL;
|
||||
zend_file_handle_dtor(&fake);
|
||||
|
||||
dataptr->op_array = ret;
|
||||
if (dataptr->op_array->refcount) {
|
||||
++*dataptr->op_array->refcount;
|
||||
} else {
|
||||
dataptr->op_array->refcount = emalloc(sizeof(uint32_t));
|
||||
*dataptr->op_array->refcount = 2;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -301,6 +309,10 @@ void phpdbg_free_file_source(phpdbg_file_source *data) {
|
||||
efree(data->buf);
|
||||
}
|
||||
|
||||
if (destroy_op_array(data->op_array)) {
|
||||
efree(data->op_array);
|
||||
}
|
||||
|
||||
efree(data);
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ typedef struct {
|
||||
#if HAVE_MMAP
|
||||
void *map;
|
||||
#endif
|
||||
zend_op_array *op_array;
|
||||
uint lines;
|
||||
uint line[1];
|
||||
} phpdbg_file_source;
|
||||
|
@ -9,9 +9,7 @@ q
|
||||
[Successful compilation of %s]
|
||||
prompt> halloarray(2) {
|
||||
["%s"]=>
|
||||
array(6) {
|
||||
[11]=>
|
||||
int(0)
|
||||
array(5) {
|
||||
[13]=>
|
||||
int(1)
|
||||
[17]=>
|
||||
@ -25,10 +23,10 @@ prompt> halloarray(2) {
|
||||
}
|
||||
["A::b"]=>
|
||||
array(2) {
|
||||
[5]=>
|
||||
int(5)
|
||||
[4]=>
|
||||
int(1)
|
||||
[5]=>
|
||||
int(5)
|
||||
}
|
||||
}
|
||||
[Script ended normally]
|
||||
@ -54,5 +52,5 @@ $a = new A();
|
||||
$a->b();
|
||||
$a->b('ha');
|
||||
|
||||
var_dump(phpdbg_end_oplog(["functions" => true, "show_unexecuted" => true]));
|
||||
var_dump(phpdbg_end_oplog(["functions" => true]));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user