mirror of
https://github.com/php/php-src.git
synced 2024-09-24 03:17:26 +00:00
Merge branch 'PHP-7.1'
This commit is contained in:
commit
da223b9500
@ -266,6 +266,29 @@ int zend_build_call_graph(zend_arena **arena, zend_script *script, uint32_t buil
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
zend_call_info **zend_build_call_map(zend_arena **arena, zend_func_info *info, zend_op_array *op_array) /* {{{ */
|
||||
{
|
||||
zend_call_info **map, *call;
|
||||
if (!info->callee_info) {
|
||||
/* Don't build call map if function contains no calls */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
map = zend_arena_calloc(arena, sizeof(zend_call_info *), op_array->last);
|
||||
for (call = info->callee_info; call; call = call->next_callee) {
|
||||
int i;
|
||||
map[call->caller_init_opline - op_array->opcodes] = call;
|
||||
map[call->caller_call_opline - op_array->opcodes] = call;
|
||||
for (i = 0; i < call->num_args; i++) {
|
||||
if (call->arg_info[i].opline) {
|
||||
map[call->arg_info[i].opline - op_array->opcodes] = call;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
@ -51,6 +51,7 @@ struct _zend_func_info {
|
||||
zend_ssa ssa; /* Static Single Assignmnt Form */
|
||||
zend_call_info *caller_info; /* where this function is called from */
|
||||
zend_call_info *callee_info; /* which functions are called from this one */
|
||||
zend_call_info **call_map; /* Call info associated with init/call/send opnum */
|
||||
int num_args; /* (-1 - unknown) */
|
||||
zend_recv_arg_info *arg_info;
|
||||
zend_ssa_var_info return_info;
|
||||
@ -69,6 +70,7 @@ typedef struct _zend_call_graph {
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
int zend_build_call_graph(zend_arena **arena, zend_script *script, uint32_t build_flags, zend_call_graph *call_graph);
|
||||
zend_call_info **zend_build_call_map(zend_arena **arena, zend_func_info *info, zend_op_array *op_array);
|
||||
int zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t build_flags, zend_op_array *op_array, zend_func_info *func_info);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
@ -1357,21 +1357,24 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
|
||||
case ZEND_DO_ICALL:
|
||||
case ZEND_DO_UCALL:
|
||||
case ZEND_DO_FCALL_BY_NAME:
|
||||
if (ssa->ops[line].result_def == var && ZEND_FUNC_INFO(op_array)) {
|
||||
if (ssa->ops[line].result_def == var) {
|
||||
zend_func_info *func_info = ZEND_FUNC_INFO(op_array);
|
||||
zend_call_info *call_info = func_info->callee_info;
|
||||
|
||||
while (call_info && call_info->caller_call_opline != opline) {
|
||||
call_info = call_info->next_callee;
|
||||
zend_call_info *call_info;
|
||||
if (!func_info || !func_info->call_map) {
|
||||
break;
|
||||
}
|
||||
if (call_info) {
|
||||
if (call_info->callee_func->type == ZEND_USER_FUNCTION) {
|
||||
func_info = ZEND_FUNC_INFO(&call_info->callee_func->op_array);
|
||||
if (func_info && func_info->return_info.has_range) {
|
||||
*tmp = func_info->return_info.range;
|
||||
return 1;
|
||||
}
|
||||
|
||||
call_info = func_info->call_map[opline - op_array->opcodes];
|
||||
if (!call_info) {
|
||||
break;
|
||||
}
|
||||
if (call_info->callee_func->type == ZEND_USER_FUNCTION) {
|
||||
func_info = ZEND_FUNC_INFO(&call_info->callee_func->op_array);
|
||||
if (func_info && func_info->return_info.has_range) {
|
||||
*tmp = func_info->return_info.range;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
//TODO: we can't use type inference for internal functions at this point ???
|
||||
#if 0
|
||||
uint32_t type;
|
||||
@ -1394,7 +1397,6 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
// FIXME: support for more opcodes
|
||||
@ -3128,13 +3130,10 @@ static void zend_update_type_info(const zend_op_array *op_array,
|
||||
zend_func_info *func_info = ZEND_FUNC_INFO(op_array);
|
||||
zend_call_info *call_info;
|
||||
|
||||
if (!func_info) {
|
||||
if (!func_info || !func_info->call_map) {
|
||||
goto unknown_opcode;
|
||||
}
|
||||
call_info = func_info->callee_info;
|
||||
while (call_info && call_info->caller_call_opline != opline) {
|
||||
call_info = call_info->next_callee;
|
||||
}
|
||||
call_info = func_info->call_map[opline - op_array->opcodes];
|
||||
if (!call_info) {
|
||||
goto unknown_opcode;
|
||||
}
|
||||
@ -3556,18 +3555,14 @@ static int is_recursive_tail_call(const zend_op_array *op_array,
|
||||
{
|
||||
zend_func_info *info = ZEND_FUNC_INFO(op_array);
|
||||
|
||||
if (info->ssa.ops && info->ssa.vars &&
|
||||
if (info->ssa.ops && info->ssa.vars && info->call_map &&
|
||||
info->ssa.ops[opline - op_array->opcodes].op1_use >= 0 &&
|
||||
info->ssa.vars[info->ssa.ops[opline - op_array->opcodes].op1_use].definition >= 0) {
|
||||
|
||||
zend_op *op = op_array->opcodes + info->ssa.vars[info->ssa.ops[opline - op_array->opcodes].op1_use].definition;
|
||||
|
||||
if (op->opcode == ZEND_DO_UCALL) {
|
||||
zend_call_info *call_info = info->callee_info;
|
||||
|
||||
while (call_info && call_info->caller_call_opline != op) {
|
||||
call_info = call_info->next_callee;
|
||||
}
|
||||
zend_call_info *call_info = info->call_map[op - op_array->opcodes];
|
||||
if (call_info && op_array == &call_info->callee_func->op_array) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -978,9 +978,10 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend
|
||||
}
|
||||
|
||||
for (i = 0; i < call_graph.op_arrays_count; i++) {
|
||||
if (call_graph.op_arrays[i]->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
|
||||
func_info = ZEND_FUNC_INFO(call_graph.op_arrays[i]);
|
||||
if (func_info) {
|
||||
func_info = ZEND_FUNC_INFO(call_graph.op_arrays[i]);
|
||||
if (func_info) {
|
||||
func_info->call_map = zend_build_call_map(&ctx.arena, func_info, call_graph.op_arrays[i]);
|
||||
if (call_graph.op_arrays[i]->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
|
||||
zend_init_func_return_info(call_graph.op_arrays[i], script, &func_info->return_info);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user