/* Build CFG, Step 1: Find basic blocks starts, calculate number of blocks */
BB_START(0);
- if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->static_variables) {
- // FIXME: Really we should try to perform variable initialization
- flags |= ZEND_FUNC_TOO_DYNAMIC;
- }
for (i = 0; i < op_array->last; i++) {
zend_op *opline = op_array->opcodes + i;
switch(opline->opcode) {
}
break;
case ZEND_INCLUDE_OR_EVAL:
+ flags |= ZEND_FUNC_INDIRECT_VAR_ASSESS;
case ZEND_YIELD:
case ZEND_YIELD_FROM:
- flags |= ZEND_FUNC_TOO_DYNAMIC;
if (build_flags & ZEND_CFG_STACKLESS) {
BB_START(i + 1);
}
if ((fn = zend_hash_find_ptr(EG(function_table), Z_STR_P(zv))) != NULL) {
if (fn->type == ZEND_INTERNAL_FUNCTION) {
if (zend_string_equals_literal(Z_STR_P(zv), "extract")) {
- flags |= ZEND_FUNC_TOO_DYNAMIC;
+ flags |= ZEND_FUNC_INDIRECT_VAR_ASSESS;
} else if (zend_string_equals_literal(Z_STR_P(zv), "compact")) {
- flags |= ZEND_FUNC_TOO_DYNAMIC;
- } else if (zend_string_equals_literal(Z_STR_P(zv), "parse_str")) {
- flags |= ZEND_FUNC_TOO_DYNAMIC;
- } else if (zend_string_equals_literal(Z_STR_P(zv), "mb_parse_str")) {
- flags |= ZEND_FUNC_TOO_DYNAMIC;
+ flags |= ZEND_FUNC_INDIRECT_VAR_ASSESS;
+ } else if (zend_string_equals_literal(Z_STR_P(zv), "parse_str") &&
+ opline->extended_value == 1) {
+ flags |= ZEND_FUNC_INDIRECT_VAR_ASSESS;
+ } else if (zend_string_equals_literal(Z_STR_P(zv), "mb_parse_str") &&
+ opline->extended_value == 1) {
+ flags |= ZEND_FUNC_INDIRECT_VAR_ASSESS;
} else if (zend_string_equals_literal(Z_STR_P(zv), "get_defined_vars")) {
- flags |= ZEND_FUNC_TOO_DYNAMIC;
+ flags |= ZEND_FUNC_INDIRECT_VAR_ASSESS;
} else if (zend_string_equals_literal(Z_STR_P(zv), "func_num_args")) {
flags |= ZEND_FUNC_VARARG;
} else if (zend_string_equals_literal(Z_STR_P(zv), "func_get_arg")) {
}
break;
case ZEND_FAST_CALL:
- flags |= ZEND_FUNC_TOO_DYNAMIC;
BB_START(OP_JMP_ADDR(opline, opline->op1) - op_array->opcodes);
BB_START(i + 1);
break;
case ZEND_FAST_RET:
- flags |= ZEND_FUNC_TOO_DYNAMIC;
if (i + 1 < op_array->last) {
BB_START(i + 1);
}
BB_START(i + 1);
break;
case ZEND_CATCH:
- flags |= ZEND_FUNC_TOO_DYNAMIC;
if (!opline->result.num) {
BB_START(ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value));
}
break;
case ZEND_UNSET_VAR:
if (!(opline->extended_value & ZEND_QUICK_SET)) {
- flags |= ZEND_FUNC_TOO_DYNAMIC;
+ flags |= ZEND_FUNC_INDIRECT_VAR_ASSESS;
}
break;
case ZEND_FETCH_R:
case ZEND_FETCH_IS:
case ZEND_FETCH_UNSET:
if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_LOCAL) {
- flags |= ZEND_FUNC_TOO_DYNAMIC;
+ flags |= ZEND_FUNC_INDIRECT_VAR_ASSESS;
} else if (((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_GLOBAL ||
(opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_GLOBAL_LOCK) &&
!op_array->function_name) {
- flags |= ZEND_FUNC_TOO_DYNAMIC;
+ flags |= ZEND_FUNC_INDIRECT_VAR_ASSESS;
}
break;
}
}
break;
case ZEND_BIND_GLOBAL:
+ tmp = (MAY_BE_REF | MAY_BE_ANY);
+ UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
+ break;
case ZEND_BIND_STATIC:
- tmp = (MAY_BE_REF | MAY_BE_ANY );
+ tmp = MAY_BE_ANY | (opline->extended_value ? MAY_BE_REF : (MAY_BE_RC1 | MAY_BE_RCN));
UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
break;
case ZEND_SEND_VAR:
}
ssa_var_info = ssa->var_info;
- for (i = 0; i < op_array->last_var; i++) {
- if (!op_array->function_name) {
+ if (!op_array->function_name) {
+ for (i = 0; i < op_array->last_var; i++) {
ssa_var_info[i].type = MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
- } else if (i == EX_VAR_TO_NUM(op_array->this_var)) {
- ssa_var_info[i].type = MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_OBJECT;
- ssa_var_info[i].ce = op_array->scope;
- ssa_var_info[i].is_instanceof = 1;
- } else {
- ssa_var_info[i].type = MAY_BE_UNDEF | MAY_BE_RCN;
+ ssa_var_info[i].has_range = 0;
+ }
+ } else {
+ for (i = 0; i < op_array->last_var; i++) {
+ if (i == EX_VAR_TO_NUM(op_array->this_var)) {
+ ssa_var_info[i].type = MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_OBJECT;
+ ssa_var_info[i].ce = op_array->scope;
+ ssa_var_info[i].is_instanceof = 1;
+ } else {
+ ssa_var_info[i].type = MAY_BE_UNDEF | MAY_BE_RCN;
+ }
+ ssa_var_info[i].has_range = 0;
}
- ssa_var_info[i].has_range = 0;
}
for (i = op_array->last_var; i < ssa->vars_count; i++) {
ssa_var_info[i].type = 0;