static void zend_dump_pi_constraint(const zend_op_array *op_array, const zend_ssa *ssa, const zend_ssa_pi_constraint *r, uint32_t dump_flags) { if (r->type_mask != (uint32_t) -1) { fprintf(stderr, " TYPE"); zend_dump_type_info(r->type_mask, NULL, 0, dump_flags); return; } if (r->range.underflow && r->range.overflow) { return; } fprintf(stderr, " RANGE"); if (r->negative) { fprintf(stderr, "~"); } fprintf(stderr, "["); if (r->range.underflow) { fprintf(stderr, "-- .. "); } else { if (r->min_ssa_var >= 0) { zend_dump_ssa_var(op_array, ssa, r->min_ssa_var, (r->min_var < op_array->last_var ? IS_CV : 0), r->min_var, dump_flags); if (r->range.min > 0) { fprintf(stderr, " + " ZEND_LONG_FMT, r->range.min); } else if (r->range.min < 0) { fprintf(stderr, " - " ZEND_LONG_FMT, -r->range.min); } fprintf(stderr, " .. "); } else { fprintf(stderr, ZEND_LONG_FMT " .. ", r->range.min); } } if (r->range.overflow) { fprintf(stderr, "++]"); } else { if (r->max_ssa_var >= 0) { zend_dump_ssa_var(op_array, ssa, r->max_ssa_var, (r->max_var < op_array->last_var ? IS_CV : 0), r->max_var, dump_flags); if (r->range.max > 0) { fprintf(stderr, " + " ZEND_LONG_FMT, r->range.max); } else if (r->range.max < 0) { fprintf(stderr, " - " ZEND_LONG_FMT, -r->range.max); } fprintf(stderr, "]"); } else { fprintf(stderr, ZEND_LONG_FMT "]", r->range.max); } } }
static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *b, const zend_op *opline, uint32_t dump_flags, const void *data) { const char *name = zend_get_opcode_name(opline->opcode); uint32_t flags = zend_get_opcode_flags(opline->opcode); uint32_t n = 0; int len = 0; const zend_ssa *ssa = NULL; if (dump_flags & ZEND_DUMP_SSA) { ssa = (const zend_ssa*)data; } if (!b) { len = fprintf(stderr, "L%u (%u):", (uint32_t)(opline - op_array->opcodes), opline->lineno); } fprintf(stderr, "%*c", 12-len, ' '); if (!ssa || !ssa->ops || ssa->ops[opline - op_array->opcodes].result_use < 0) { if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) { if (ssa && ssa->ops && ssa->ops[opline - op_array->opcodes].result_def >= 0) { int ssa_var_num = ssa->ops[opline - op_array->opcodes].result_def; zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->result_type, EX_VAR_TO_NUM(opline->result.var), dump_flags); } else { zend_dump_var(op_array, opline->result_type, EX_VAR_TO_NUM(opline->result.var)); } fprintf(stderr, " = "); } } if (name) { fprintf(stderr, "%s", (name + 5)); } else { fprintf(stderr, "OP_%d", (int)opline->opcode); } if (ZEND_VM_EXT_NUM == (flags & ZEND_VM_EXT_MASK)) { fprintf(stderr, " %u", opline->extended_value); } else if (ZEND_VM_EXT_DIM_OBJ == (flags & ZEND_VM_EXT_MASK)) { if (opline->extended_value == ZEND_ASSIGN_DIM) { fprintf(stderr, " (dim)"); } else if (opline->extended_value == ZEND_ASSIGN_OBJ) { fprintf(stderr, " (obj)"); } } else if (ZEND_VM_EXT_TYPE == (flags & ZEND_VM_EXT_MASK)) { switch (opline->extended_value) { case IS_NULL: fprintf(stderr, " (null)"); break; case IS_FALSE: fprintf(stderr, " (false)"); break; case IS_TRUE: fprintf(stderr, " (true)"); break; case IS_LONG: fprintf(stderr, " (long)"); break; case IS_DOUBLE: fprintf(stderr, " (double)"); break; case IS_STRING: fprintf(stderr, " (string)"); break; case IS_ARRAY: fprintf(stderr, " (array)"); break; case IS_OBJECT: fprintf(stderr, " (object)"); break; case IS_RESOURCE: fprintf(stderr, " (resource)"); break; case _IS_BOOL: fprintf(stderr, " (bool)"); break; case IS_CALLABLE: fprintf(stderr, " (callable)"); break; case IS_VOID: fprintf(stderr, " (void)"); break; default: fprintf(stderr, " (\?\?\?)"); break; } } else if (ZEND_VM_EXT_TYPE_MASK == (flags & ZEND_VM_EXT_MASK)) { switch (opline->extended_value) { case (1<<IS_NULL): fprintf(stderr, " (null)"); break; case (1<<IS_FALSE): fprintf(stderr, " (false)"); break; case (1<<IS_TRUE): fprintf(stderr, " (true)"); break; case (1<<IS_LONG): fprintf(stderr, " (long)"); break; case (1<<IS_DOUBLE): fprintf(stderr, " (double)"); break; case (1<<IS_STRING): fprintf(stderr, " (string)"); break; case (1<<IS_ARRAY): fprintf(stderr, " (array)"); break; case (1<<IS_OBJECT): fprintf(stderr, " (object)"); break; case (1<<IS_RESOURCE): fprintf(stderr, " (resource)"); break; case ((1<<IS_FALSE)|(1<<IS_TRUE)): fprintf(stderr, " (bool)"); break; default: fprintf(stderr, " (\?\?\?)"); break; } } else if (ZEND_VM_EXT_EVAL == (flags & ZEND_VM_EXT_MASK)) { switch (opline->extended_value) { case ZEND_EVAL: fprintf(stderr, " (eval)"); break; case ZEND_INCLUDE: fprintf(stderr, " (include)"); break; case ZEND_INCLUDE_ONCE: fprintf(stderr, " (include_once)"); break; case ZEND_REQUIRE: fprintf(stderr, " (require)"); break; case ZEND_REQUIRE_ONCE: fprintf(stderr, " (require_once)"); break; default: fprintf(stderr, " (\?\?\?)"); break; } } else if (ZEND_VM_EXT_SRC == (flags & ZEND_VM_EXT_MASK)) { if (opline->extended_value == ZEND_RETURNS_VALUE) { fprintf(stderr, " (value)"); } else if (opline->extended_value == ZEND_RETURNS_FUNCTION) { fprintf(stderr, " (function)"); } } else { if (ZEND_VM_EXT_VAR_FETCH & flags) { if (opline->extended_value & ZEND_FETCH_GLOBAL) { fprintf(stderr, " (global)"); } else if (opline->extended_value & ZEND_FETCH_LOCAL) { fprintf(stderr, " (local)"); } else if (opline->extended_value & ZEND_FETCH_GLOBAL_LOCK) { fprintf(stderr, " (global+lock)"); } } if (ZEND_VM_EXT_ISSET & flags) { if (!(opline->extended_value & ZEND_ISEMPTY)) { fprintf(stderr, " (isset)"); } else { fprintf(stderr, " (empty)"); } } if (ZEND_VM_EXT_ARRAY_INIT & flags) { fprintf(stderr, " %u", opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT); if (!(opline->extended_value & ZEND_ARRAY_NOT_PACKED)) { fprintf(stderr, " (packed)"); } } if (ZEND_VM_EXT_REF & flags) { if (opline->extended_value & ZEND_ARRAY_ELEMENT_REF) { fprintf(stderr, " (ref)"); } } }
static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *b, const zend_op *opline, uint32_t dump_flags, const void *data) { const char *name = zend_get_opcode_name(opline->opcode); uint32_t flags = zend_get_opcode_flags(opline->opcode); uint32_t n = 0; int len = 0; const zend_ssa *ssa = NULL; if (dump_flags & ZEND_DUMP_SSA) { ssa = (const zend_ssa*)data; } if (!b) { len = fprintf(stderr, "L%u:", (uint32_t)(opline - op_array->opcodes)); } fprintf(stderr, "%*c", 8-len, ' '); if (!ssa || !ssa->ops || ssa->ops[opline - op_array->opcodes].result_use < 0) { if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) { if (ssa && ssa->ops) { int ssa_var_num = ssa->ops[opline - op_array->opcodes].result_def; ZEND_ASSERT(ssa_var_num >= 0); zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->result_type, EX_VAR_TO_NUM(opline->result.var), dump_flags); } else { zend_dump_var(op_array, opline->result_type, EX_VAR_TO_NUM(opline->result.var)); } fprintf(stderr, " = "); } } if (name) { fprintf(stderr, "%s", (name + 5)); } else { fprintf(stderr, "OP_%d", (int)opline->opcode); } if (ZEND_VM_EXT_NUM == (flags & ZEND_VM_EXT_MASK)) { fprintf(stderr, " %u", opline->extended_value); } else if (ZEND_VM_EXT_DIM_OBJ == (flags & ZEND_VM_EXT_MASK)) { if (opline->extended_value == ZEND_ASSIGN_DIM) { fprintf(stderr, " (dim)"); } else if (opline->extended_value == ZEND_ASSIGN_OBJ) { fprintf(stderr, " (obj)"); } } else if (ZEND_VM_EXT_CLASS_FETCH == (flags & ZEND_VM_EXT_MASK)) { zend_dump_class_fetch_type(opline->extended_value); } else if (ZEND_VM_EXT_CONST_FETCH == (flags & ZEND_VM_EXT_MASK)) { if (opline->extended_value & IS_CONSTANT_UNQUALIFIED) { fprintf(stderr, " (unqualified)"); } if (opline->extended_value & IS_CONSTANT_CLASS) { fprintf(stderr, " (__class__)"); } if (opline->extended_value & IS_CONSTANT_IN_NAMESPACE) { fprintf(stderr, " (in-namespace)"); } } else if (ZEND_VM_EXT_TYPE == (flags & ZEND_VM_EXT_MASK)) { switch (opline->extended_value) { case IS_NULL: fprintf(stderr, " (null)"); break; case IS_FALSE: fprintf(stderr, " (false)"); break; case IS_TRUE: fprintf(stderr, " (true)"); break; case IS_LONG: fprintf(stderr, " (long)"); break; case IS_DOUBLE: fprintf(stderr, " (double)"); break; case IS_STRING: fprintf(stderr, " (string)"); break; case IS_ARRAY: fprintf(stderr, " (array)"); break; case IS_OBJECT: fprintf(stderr, " (object)"); break; case IS_RESOURCE: fprintf(stderr, " (resource)"); break; case _IS_BOOL: fprintf(stderr, " (bool)"); break; case IS_CALLABLE: fprintf(stderr, " (callable)"); break; case IS_VOID: fprintf(stderr, " (void)"); break; default: fprintf(stderr, " (\?\?\?)"); break; } } else if (ZEND_VM_EXT_EVAL == (flags & ZEND_VM_EXT_MASK)) { switch (opline->extended_value) { case ZEND_EVAL: fprintf(stderr, " (eval)"); break; case ZEND_INCLUDE: fprintf(stderr, " (include)"); break; case ZEND_INCLUDE_ONCE: fprintf(stderr, " (include_once)"); break; case ZEND_REQUIRE: fprintf(stderr, " (require)"); break; case ZEND_REQUIRE_ONCE: fprintf(stderr, " (require_once)"); break; default: fprintf(stderr, " (\?\?\?)"); break; } } else if (ZEND_VM_EXT_FAST_CALL == (flags & ZEND_VM_EXT_MASK)) { if (opline->extended_value == ZEND_FAST_CALL_FROM_FINALLY) { fprintf(stderr, " (from-finally)"); } } else if (ZEND_VM_EXT_FAST_RET == (flags & ZEND_VM_EXT_MASK)) { if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) { fprintf(stderr, " (to-catch)"); } else if (opline->extended_value == ZEND_FAST_RET_TO_FINALLY) { fprintf(stderr, " (to-finally)"); } } else if (ZEND_VM_EXT_SRC == (flags & ZEND_VM_EXT_MASK)) { if (opline->extended_value == ZEND_RETURNS_VALUE) { fprintf(stderr, " (value)"); } else if (opline->extended_value == ZEND_RETURNS_FUNCTION) { fprintf(stderr, " (function)"); } } else if (ZEND_VM_EXT_SEND == (flags & ZEND_VM_EXT_MASK)) { if (opline->extended_value & ZEND_ARG_SEND_BY_REF) { fprintf(stderr, " (ref)"); } if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { fprintf(stderr, " (compile-time)"); } if (opline->extended_value & ZEND_ARG_SEND_FUNCTION) { fprintf(stderr, " (function)"); } if (opline->extended_value & ZEND_ARG_SEND_SILENT) { fprintf(stderr, " (silent)"); } } else { if (ZEND_VM_EXT_VAR_FETCH & flags) { switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) { case ZEND_FETCH_GLOBAL: fprintf(stderr, " (global)"); break; case ZEND_FETCH_LOCAL: fprintf(stderr, " (local)"); break; case ZEND_FETCH_GLOBAL_LOCK: fprintf(stderr, " (global+lock)"); break; } } if (ZEND_VM_EXT_ISSET & flags) { if (opline->extended_value & ZEND_QUICK_SET) { fprintf(stderr, " (quick)"); } if (opline->extended_value & ZEND_ISSET) { fprintf(stderr, " (isset)"); } else if (opline->extended_value & ZEND_ISEMPTY) { fprintf(stderr, " (empty)"); } } if (ZEND_VM_EXT_ARG_NUM & flags) { fprintf(stderr, " %u", opline->extended_value & ZEND_FETCH_ARG_MASK); } if (ZEND_VM_EXT_ARRAY_INIT & flags) { fprintf(stderr, " %u", opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT); if (!(opline->extended_value & ZEND_ARRAY_NOT_PACKED)) { fprintf(stderr, " (packed)"); } } if (ZEND_VM_EXT_REF & flags) { if (opline->extended_value & ZEND_ARRAY_ELEMENT_REF) { fprintf(stderr, " (ref)"); } } }