Exemplo n.º 1
0
/* e-SSA construction: Pi placement (Pi is actually a Phi with single
 * source and constraint).
 * Order of Phis is importent, Pis must be placed before Phis
 */
static void place_essa_pis(
		zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa,
		zend_dfg *dfg) {
	zend_basic_block *blocks = ssa->cfg.blocks;
	int j, blocks_count = ssa->cfg.blocks_count;
	for (j = 0; j < blocks_count; j++) {
		zend_ssa_phi *pi;
		zend_op *opline = op_array->opcodes + ssa->cfg.blocks[j].end;
		int bt; /* successor block number if a condition is true */
		int bf; /* successor block number if a condition is false */

		if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) {
			continue;
		}
		/* the last instruction of basic block is conditional branch,
		 * based on comparison of CV(s)
		 */
		switch (opline->opcode) {
			case ZEND_JMPZ:
			case ZEND_JMPZNZ:
				bf = ssa->cfg.blocks[j].successors[0];
				bt = ssa->cfg.blocks[j].successors[1];
				break;
			case ZEND_JMPNZ:
				bt = ssa->cfg.blocks[j].successors[0];
				bf = ssa->cfg.blocks[j].successors[1];
				break;
			default:
				continue;
		}
		if (opline->op1_type == IS_TMP_VAR &&
		    ((opline-1)->opcode == ZEND_IS_EQUAL ||
		     (opline-1)->opcode == ZEND_IS_NOT_EQUAL ||
		     (opline-1)->opcode == ZEND_IS_SMALLER ||
		     (opline-1)->opcode == ZEND_IS_SMALLER_OR_EQUAL) &&
		    opline->op1.var == (opline-1)->result.var) {
			int  var1 = -1;
			int  var2 = -1;
			zend_long val1 = 0;
			zend_long val2 = 0;
//			long val = 0;

			if ((opline-1)->op1_type == IS_CV) {
				var1 = EX_VAR_TO_NUM((opline-1)->op1.var);
			} else if ((opline-1)->op1_type == IS_TMP_VAR) {
				var1 = find_adjusted_tmp_var(
					op_array, build_flags, opline, (opline-1)->op1.var, &val2);
			}

			if ((opline-1)->op2_type == IS_CV) {
				var2 = EX_VAR_TO_NUM((opline-1)->op2.var);
			} else if ((opline-1)->op2_type == IS_TMP_VAR) {
				var2 = find_adjusted_tmp_var(
					op_array, build_flags, opline, (opline-1)->op2.var, &val1);
			}

			if (var1 >= 0 && var2 >= 0) {
				if (!sub_will_overflow(val1, val2) && !sub_will_overflow(val2, val1)) {
					zend_long tmp = val1;
					val1 -= val2;
					val2 -= tmp;
				} else {
					var1 = -1;
					var2 = -1;
				}
			} else if (var1 >= 0 && var2 < 0) {
				zend_long add_val2 = 0;
				if ((opline-1)->op2_type == IS_CONST &&
				    Z_TYPE_P(CRT_CONSTANT((opline-1)->op2)) == IS_LONG) {
					add_val2 = Z_LVAL_P(CRT_CONSTANT((opline-1)->op2));
				} else if ((opline-1)->op2_type == IS_CONST &&
				    Z_TYPE_P(CRT_CONSTANT((opline-1)->op2)) == IS_FALSE) {
					add_val2 = 0;
				} else if ((opline-1)->op2_type == IS_CONST &&
				    Z_TYPE_P(CRT_CONSTANT((opline-1)->op2)) == IS_TRUE) {
					add_val2 = 1;
				} else {
					var1 = -1;
				}
				if (!add_will_overflow(val2, add_val2)) {
					val2 += add_val2;
				} else {
					var1 = -1;
				}
			} else if (var1 < 0 && var2 >= 0) {
				zend_long add_val1 = 0;
				if ((opline-1)->op1_type == IS_CONST &&
				    Z_TYPE_P(CRT_CONSTANT((opline-1)->op1)) == IS_LONG) {
					add_val1 = Z_LVAL_P(CRT_CONSTANT((opline-1)->op1));
				} else if ((opline-1)->op1_type == IS_CONST &&
				    Z_TYPE_P(CRT_CONSTANT((opline-1)->op1)) == IS_FALSE) {
					add_val1 = 0;
				} else if ((opline-1)->op1_type == IS_CONST &&
				    Z_TYPE_P(CRT_CONSTANT((opline-1)->op1)) == IS_TRUE) {
					add_val1 = 1;
				} else {
					var2 = -1;
				}
				if (!add_will_overflow(val1, add_val1)) {
					val1 += add_val1;
				} else {
					var2 = -1;
				}
			}

			if (var1 >= 0) {
				if ((opline-1)->opcode == ZEND_IS_EQUAL) {
					if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var1))) {
						pi_range_equals(pi, var2, val2);
					}
					if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var1))) {
						pi_range_not_equals(pi, var2, val2);
					}
				} else if ((opline-1)->opcode == ZEND_IS_NOT_EQUAL) {
					if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var1))) {
						pi_range_equals(pi, var2, val2);
					}
					if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var1))) {
						pi_range_not_equals(pi, var2, val2);
					}
				} else if ((opline-1)->opcode == ZEND_IS_SMALLER) {
					if (val2 > ZEND_LONG_MIN) {
						if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var1))) {
							pi_range_max(pi, var2, val2-1);
						}
					}
					if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var1))) {
						pi_range_min(pi, var2, val2);
					}
				} else if ((opline-1)->opcode == ZEND_IS_SMALLER_OR_EQUAL) {
					if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var1))) {
						pi_range_max(pi, var2, val2);
					}
					if (val2 < ZEND_LONG_MAX) {
						if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var1))) {
							pi_range_min(pi, var2, val2+1);
						}
					}
				}
			}
			if (var2 >= 0) {
				if((opline-1)->opcode == ZEND_IS_EQUAL) {
					if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var2))) {
						pi_range_equals(pi, var1, val1);
					}
					if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var2))) {
						pi_range_not_equals(pi, var1, val1);
					}
				} else if ((opline-1)->opcode == ZEND_IS_NOT_EQUAL) {
					if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var2))) {
						pi_range_equals(pi, var1, val1);
					}
					if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var2))) {
						pi_range_not_equals(pi, var1, val1);
					}
				} else if ((opline-1)->opcode == ZEND_IS_SMALLER) {
					if (val1 < ZEND_LONG_MAX) {
						if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var2))) {
							pi_range_min(pi, var1, val1+1);
						}
					}
					if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var2))) {
						pi_range_max(pi, var1, val1);
					}
				} else if ((opline-1)->opcode == ZEND_IS_SMALLER_OR_EQUAL) {
					if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var2))) {
						pi_range_min(pi, var1, val1);
					}
					if (val1 > ZEND_LONG_MIN) {
						if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var2))) {
							pi_range_max(pi, var1, val1-1);
						}
					}
				}
			}
		} else if (opline->op1_type == IS_TMP_VAR &&
		           ((opline-1)->opcode == ZEND_POST_INC ||
		            (opline-1)->opcode == ZEND_POST_DEC) &&
		           opline->op1.var == (opline-1)->result.var &&
		           (opline-1)->op1_type == IS_CV) {
			int var = EX_VAR_TO_NUM((opline-1)->op1.var);

			if ((opline-1)->opcode == ZEND_POST_DEC) {
				if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var))) {
					pi_range_equals(pi, -1, -1);
				}
				if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var))) {
					pi_range_not_equals(pi, -1, -1);
				}
			} else if ((opline-1)->opcode == ZEND_POST_INC) {
				if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var))) {
					pi_range_equals(pi, -1, 1);
				}
				if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var))) {
					pi_range_not_equals(pi, -1, 1);
				}
			}
		} else if (opline->op1_type == IS_VAR &&
		           ((opline-1)->opcode == ZEND_PRE_INC ||
		            (opline-1)->opcode == ZEND_PRE_DEC) &&
		           opline->op1.var == (opline-1)->result.var &&
		           (opline-1)->op1_type == IS_CV) {
			int var = EX_VAR_TO_NUM((opline-1)->op1.var);

			if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var))) {
				pi_range_equals(pi, -1, 0);
			}
			/* speculative */
			if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var))) {
				pi_range_not_equals(pi, -1, 0);
			}
		} else if (opline->op1_type == IS_TMP_VAR && (opline-1)->opcode == ZEND_TYPE_CHECK &&
				   opline->op1.var == (opline-1)->result.var && (opline-1)->op1_type == IS_CV) {
			int var = EX_VAR_TO_NUM((opline-1)->op1.var);
			uint32_t type = (opline-1)->extended_value;
			if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var))) {
				pi_type_mask(pi, mask_for_type_check(type));
			}
			if (type != IS_OBJECT && type != IS_RESOURCE) {
				/* is_object() and is_resource() may return false, even though the value is
				 * an object/resource. */
				if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var))) {
					pi_not_type_mask(pi, mask_for_type_check(type));
				}
			}
		} else if (opline->op1_type == IS_TMP_VAR &&
				   ((opline-1)->opcode == ZEND_IS_IDENTICAL
					|| (opline-1)->opcode == ZEND_IS_NOT_IDENTICAL) &&
				   opline->op1.var == (opline-1)->result.var) {
			int var;
			zval *val;
			uint32_t type_mask;
			if ((opline-1)->op1_type == IS_CV && (opline-1)->op2_type == IS_CONST) {
				var = EX_VAR_TO_NUM((opline-1)->op1.var);
				val = CRT_CONSTANT((opline-1)->op2);
			} else if ((opline-1)->op1_type == IS_CONST && (opline-1)->op2_type == IS_CV) {
				var = EX_VAR_TO_NUM((opline-1)->op2.var);
				val = CRT_CONSTANT((opline-1)->op1);
			} else {
				continue;
			}

			/* We're interested in === null/true/false comparisons here, because they eliminate
			 * a type in the false-branch. Other === VAL comparisons are unlikely to be useful. */
			if (Z_TYPE_P(val) != IS_NULL && Z_TYPE_P(val) != IS_TRUE && Z_TYPE_P(val) != IS_FALSE) {
				continue;
			}

			type_mask = _const_op_type(val);
			if ((opline-1)->opcode == ZEND_IS_IDENTICAL) {
				if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var))) {
					pi_type_mask(pi, type_mask);
				}
				if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var))) {
					pi_not_type_mask(pi, type_mask);
				}
			} else {
				if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var))) {
					pi_type_mask(pi, type_mask);
				}
				if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var))) {
					pi_not_type_mask(pi, type_mask);
				}
			}
		}
	}
}
Exemplo n.º 2
0
Arquivo: test1.c Projeto: Mric26/M2-S1
void print_part1() {
	printf("VERSION=%s\n", VERSION);
	printf("PI=%lg\n", PI);	
	printf("pi()=%lg\n", pi());
	printf("PI+5=%lg\n", add_pi(5));
}