12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262 |
- /*
- +----------------------------------------------------------------------+
- | Zend Engine, Bytecode Visualisation |
- +----------------------------------------------------------------------+
- | Copyright (c) The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | https://www.php.net/license/3_01.txt |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Dmitry Stogov <dmitry@php.net> |
- +----------------------------------------------------------------------+
- */
- #include "zend_compile.h"
- #include "zend_cfg.h"
- #include "zend_ssa.h"
- #include "zend_inference.h"
- #include "zend_func_info.h"
- #include "zend_call_graph.h"
- #include "zend_dump.h"
- void zend_dump_ht(HashTable *ht)
- {
- zend_ulong index;
- zend_string *key;
- zval *val;
- int first = 1;
- ZEND_HASH_FOREACH_KEY_VAL(ht, index, key, val) {
- if (first) {
- first = 0;
- } else {
- fprintf(stderr, ", ");
- }
- if (key) {
- fprintf(stderr, "\"%s\"", ZSTR_VAL(key));
- } else {
- fprintf(stderr, ZEND_LONG_FMT, index);
- }
- fprintf(stderr, " =>");
- zend_dump_const(val);
- } ZEND_HASH_FOREACH_END();
- }
- void zend_dump_const(const zval *zv)
- {
- switch (Z_TYPE_P(zv)) {
- case IS_NULL:
- fprintf(stderr, " null");
- break;
- case IS_FALSE:
- fprintf(stderr, " bool(false)");
- break;
- case IS_TRUE:
- fprintf(stderr, " bool(true)");
- break;
- case IS_LONG:
- fprintf(stderr, " int(" ZEND_LONG_FMT ")", Z_LVAL_P(zv));
- break;
- case IS_DOUBLE:
- fprintf(stderr, " float(%g)", Z_DVAL_P(zv));
- break;
- case IS_STRING:
- fprintf(stderr, " string(\"%s\")", Z_STRVAL_P(zv));
- break;
- case IS_ARRAY:
- fprintf(stderr, " array(...)");
- break;
- default:
- fprintf(stderr, " zval(type=%d)", Z_TYPE_P(zv));
- break;
- }
- }
- static void zend_dump_class_fetch_type(uint32_t fetch_type)
- {
- switch (fetch_type & ZEND_FETCH_CLASS_MASK) {
- case ZEND_FETCH_CLASS_SELF:
- fprintf(stderr, " (self)");
- break;
- case ZEND_FETCH_CLASS_PARENT:
- fprintf(stderr, " (parent)");
- break;
- case ZEND_FETCH_CLASS_STATIC:
- fprintf(stderr, " (static)");
- break;
- case ZEND_FETCH_CLASS_AUTO:
- fprintf(stderr, " (auto)");
- break;
- case ZEND_FETCH_CLASS_INTERFACE:
- fprintf(stderr, " (interface)");
- break;
- case ZEND_FETCH_CLASS_TRAIT:
- fprintf(stderr, " (trait)");
- break;
- }
- if (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) {
- fprintf(stderr, " (no-autoload)");
- }
- if (fetch_type & ZEND_FETCH_CLASS_SILENT) {
- fprintf(stderr, " (silent)");
- }
- if (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) {
- fprintf(stderr, " (exception)");
- }
- }
- static void zend_dump_unused_op(const zend_op *opline, znode_op op, uint32_t flags) {
- if (ZEND_VM_OP_NUM == (flags & ZEND_VM_OP_MASK)) {
- fprintf(stderr, " %u", op.num);
- } else if (ZEND_VM_OP_TRY_CATCH == (flags & ZEND_VM_OP_MASK)) {
- if (op.num != (uint32_t)-1) {
- fprintf(stderr, " try-catch(%u)", op.num);
- }
- } else if (ZEND_VM_OP_THIS == (flags & ZEND_VM_OP_MASK)) {
- fprintf(stderr, " THIS");
- } else if (ZEND_VM_OP_NEXT == (flags & ZEND_VM_OP_MASK)) {
- fprintf(stderr, " NEXT");
- } else if (ZEND_VM_OP_CLASS_FETCH == (flags & ZEND_VM_OP_MASK)) {
- zend_dump_class_fetch_type(op.num);
- } else if (ZEND_VM_OP_CONSTRUCTOR == (flags & ZEND_VM_OP_MASK)) {
- fprintf(stderr, " CONSTRUCTOR");
- } else if (ZEND_VM_OP_CONST_FETCH == (flags & ZEND_VM_OP_MASK)) {
- if (op.num & IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE) {
- fprintf(stderr, " (unqualified-in-namespace)");
- }
- }
- }
- ZEND_API void zend_dump_var(const zend_op_array *op_array, zend_uchar var_type, int var_num)
- {
- if (var_type == IS_CV && var_num < op_array->last_var) {
- fprintf(stderr, "CV%d($%s)", var_num, op_array->vars[var_num]->val);
- } else if (var_type == IS_VAR) {
- fprintf(stderr, "V%d", var_num);
- } else if ((var_type & (IS_VAR|IS_TMP_VAR)) == IS_TMP_VAR) {
- fprintf(stderr, "T%d", var_num);
- } else {
- fprintf(stderr, "X%d", var_num);
- }
- }
- static void zend_dump_range(const zend_ssa_range *r)
- {
- if (r->underflow && r->overflow) {
- return;
- }
- fprintf(stderr, " RANGE[");
- if (r->underflow) {
- fprintf(stderr, "--..");
- } else if (r->min == ZEND_LONG_MIN) {
- fprintf(stderr, "MIN..");
- } else {
- fprintf(stderr, ZEND_LONG_FMT "..", r->min);
- }
- if (r->overflow) {
- fprintf(stderr, "++]");
- } else if (r->max == ZEND_LONG_MAX) {
- fprintf(stderr, "MAX]");
- } else {
- fprintf(stderr, ZEND_LONG_FMT "]", r->max);
- }
- }
- static void zend_dump_type_info(uint32_t info, zend_class_entry *ce, int is_instanceof, uint32_t dump_flags)
- {
- int first = 1;
- fprintf(stderr, " [");
- if (info & MAY_BE_GUARD) {
- fprintf(stderr, "!");
- }
- if (info & MAY_BE_UNDEF) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "undef");
- }
- if (info & MAY_BE_INDIRECT) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "ind");
- }
- if (info & MAY_BE_REF) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "ref");
- }
- if (dump_flags & ZEND_DUMP_RC_INFERENCE) {
- if (info & MAY_BE_RC1) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "rc1");
- }
- if (info & MAY_BE_RCN) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "rcn");
- }
- }
- if (info & MAY_BE_CLASS) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "class");
- if (ce) {
- if (is_instanceof) {
- fprintf(stderr, " (instanceof %s)", ce->name->val);
- } else {
- fprintf(stderr, " (%s)", ce->name->val);
- }
- }
- } else if ((info & MAY_BE_ANY) == MAY_BE_ANY) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "any");
- } else {
- if (info & MAY_BE_NULL) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "null");
- }
- if ((info & MAY_BE_FALSE) && (info & MAY_BE_TRUE)) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "bool");
- } else if (info & MAY_BE_FALSE) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "false");
- } else if (info & MAY_BE_TRUE) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "true");
- }
- if (info & MAY_BE_LONG) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "long");
- }
- if (info & MAY_BE_DOUBLE) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "double");
- }
- if (info & MAY_BE_STRING) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "string");
- }
- if (info & MAY_BE_ARRAY) {
- if (first) first = 0; else fprintf(stderr, ", ");
- if (!(info & MAY_BE_ARRAY_KEY_STRING) || (info & MAY_BE_PACKED_GUARD)) {
- if (MAY_BE_PACKED_ONLY(info)) {
- if (info & MAY_BE_PACKED_GUARD) {
- fprintf(stderr, "!");
- }
- fprintf(stderr, "packed ");
- } else if (MAY_BE_HASH_ONLY(info)) {
- if (info & MAY_BE_PACKED_GUARD) {
- fprintf(stderr, "!");
- }
- fprintf(stderr, "hash ");
- }
- }
- fprintf(stderr, "array");
- if ((info & MAY_BE_ARRAY_KEY_ANY) != 0 &&
- ((info & MAY_BE_ARRAY_KEY_LONG) == 0 ||
- (info & MAY_BE_ARRAY_KEY_STRING) == 0)) {
- int afirst = 1;
- fprintf(stderr, " [");
- if (info & MAY_BE_ARRAY_KEY_LONG) {
- if (afirst) afirst = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "long");
- }
- if (info & MAY_BE_ARRAY_KEY_STRING) {
- if (afirst) afirst = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "string");
- }
- fprintf(stderr, "]");
- }
- if (info & (MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF)) {
- int afirst = 1;
- fprintf(stderr, " of [");
- if ((info & MAY_BE_ARRAY_OF_ANY) == MAY_BE_ARRAY_OF_ANY) {
- if (afirst) afirst = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "any");
- } else {
- if (info & MAY_BE_ARRAY_OF_NULL) {
- if (afirst) afirst = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "null");
- }
- if (info & MAY_BE_ARRAY_OF_FALSE) {
- if (afirst) afirst = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "false");
- }
- if (info & MAY_BE_ARRAY_OF_TRUE) {
- if (afirst) afirst = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "true");
- }
- if (info & MAY_BE_ARRAY_OF_LONG) {
- if (afirst) afirst = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "long");
- }
- if (info & MAY_BE_ARRAY_OF_DOUBLE) {
- if (afirst) afirst = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "double");
- }
- if (info & MAY_BE_ARRAY_OF_STRING) {
- if (afirst) afirst = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "string");
- }
- if (info & MAY_BE_ARRAY_OF_ARRAY) {
- if (afirst) afirst = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "array");
- }
- if (info & MAY_BE_ARRAY_OF_OBJECT) {
- if (afirst) afirst = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "object");
- }
- if (info & MAY_BE_ARRAY_OF_RESOURCE) {
- if (afirst) afirst = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "resource");
- }
- }
- if (info & MAY_BE_ARRAY_OF_REF) {
- if (afirst) afirst = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "ref");
- }
- fprintf(stderr, "]");
- }
- }
- if (info & MAY_BE_OBJECT) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "object");
- if (ce) {
- if (is_instanceof) {
- fprintf(stderr, " (instanceof %s)", ce->name->val);
- } else {
- fprintf(stderr, " (%s)", ce->name->val);
- }
- }
- }
- if (info & MAY_BE_RESOURCE) {
- if (first) first = 0; else fprintf(stderr, ", ");
- fprintf(stderr, "resource");
- }
- }
- fprintf(stderr, "]");
- }
- static void zend_dump_ssa_var_info(const zend_ssa *ssa, int ssa_var_num, uint32_t dump_flags)
- {
- zend_dump_type_info(
- ssa->var_info[ssa_var_num].type,
- ssa->var_info[ssa_var_num].ce,
- ssa->var_info[ssa_var_num].ce ?
- ssa->var_info[ssa_var_num].is_instanceof : 0,
- dump_flags);
- }
- ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int ssa_var_num, zend_uchar var_type, int var_num, uint32_t dump_flags)
- {
- if (ssa_var_num >= 0) {
- fprintf(stderr, "#%d.", ssa_var_num);
- } else {
- fprintf(stderr, "#?.");
- }
- zend_dump_var(op_array, (var_num < op_array->last_var ? IS_CV : var_type), var_num);
- if (ssa_var_num >= 0 && ssa->vars) {
- if (ssa->vars[ssa_var_num].no_val) {
- fprintf(stderr, " NOVAL");
- }
- if (ssa->vars[ssa_var_num].escape_state == ESCAPE_STATE_NO_ESCAPE) {
- fprintf(stderr, " NOESC");
- }
- if (ssa->var_info) {
- zend_dump_ssa_var_info(ssa, ssa_var_num, dump_flags);
- if (ssa->var_info[ssa_var_num].has_range) {
- zend_dump_range(&ssa->var_info[ssa_var_num].range);
- }
- }
- }
- }
- static void zend_dump_type_constraint(const zend_op_array *op_array, const zend_ssa *ssa, const zend_ssa_type_constraint *constraint, uint32_t dump_flags)
- {
- fprintf(stderr, " TYPE");
- zend_dump_type_info(constraint->type_mask, constraint->ce, 1, dump_flags);
- }
- static void zend_dump_range_constraint(const zend_op_array *op_array, const zend_ssa *ssa, const zend_ssa_range_constraint *r, uint32_t dump_flags)
- {
- 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);
- }
- }
- }
- ZEND_API void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *b, const zend_op *opline, uint32_t dump_flags, const zend_ssa *ssa, const zend_ssa_op *ssa_op)
- {
- const char *name = zend_get_opcode_name(opline->opcode);
- uint32_t flags = zend_get_opcode_flags(opline->opcode);
- uint32_t n = 0;
- if (!ssa_op || ssa_op->result_use < 0) {
- if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
- if (ssa_op && ssa_op->result_def >= 0) {
- int ssa_var_num = ssa_op->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_OP == (flags & ZEND_VM_EXT_MASK)) {
- fprintf(stderr, " (%s)", zend_get_opcode_name(opline->extended_value) + 5);
- } 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;
- case IS_NEVER:
- fprintf(stderr, " (never)");
- 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, " TYPE");
- zend_dump_type_info(opline->extended_value, NULL, 0, dump_flags);
- 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)");
- }
- }
- if ((ZEND_VM_EXT_DIM_WRITE|ZEND_VM_EXT_FETCH_REF) & flags) {
- uint32_t obj_flags = opline->extended_value & ZEND_FETCH_OBJ_FLAGS;
- if (obj_flags == ZEND_FETCH_REF) {
- fprintf(stderr, " (ref)");
- } else if (obj_flags == ZEND_FETCH_DIM_WRITE) {
- fprintf(stderr, " (dim write)");
- }
- }
- }
- if (opline->op1_type == IS_CONST) {
- zend_dump_const(CRT_CONSTANT(opline->op1));
- } else if (opline->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
- if (ssa_op) {
- int ssa_var_num = ssa_op->op1_use;
- if (ssa_var_num >= 0) {
- fprintf(stderr, " ");
- zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->op1_type, EX_VAR_TO_NUM(opline->op1.var), dump_flags);
- } else if (ssa_op->op1_def < 0) {
- fprintf(stderr, " ");
- zend_dump_var(op_array, opline->op1_type, EX_VAR_TO_NUM(opline->op1.var));
- }
- } else {
- fprintf(stderr, " ");
- zend_dump_var(op_array, opline->op1_type, EX_VAR_TO_NUM(opline->op1.var));
- }
- if (ssa_op) {
- int ssa_var_num = ssa_op->op1_def;
- if (ssa_var_num >= 0) {
- fprintf(stderr, " -> ");
- zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->op1_type, EX_VAR_TO_NUM(opline->op1.var), dump_flags);
- }
- }
- } else {
- uint32_t op1_flags = ZEND_VM_OP1_FLAGS(flags);
- if (ZEND_VM_OP_JMP_ADDR == (op1_flags & ZEND_VM_OP_MASK)) {
- if (b) {
- fprintf(stderr, " BB%d", b->successors[n++]);
- } else {
- fprintf(stderr, " %04u", (uint32_t)(OP_JMP_ADDR(opline, opline->op1) - op_array->opcodes));
- }
- } else {
- zend_dump_unused_op(opline, opline->op1, op1_flags);
- }
- }
- if (opline->op2_type == IS_CONST) {
- zval *op = CRT_CONSTANT(opline->op2);
- if (
- opline->opcode == ZEND_SWITCH_LONG
- || opline->opcode == ZEND_SWITCH_STRING
- || opline->opcode == ZEND_MATCH
- ) {
- HashTable *jumptable = Z_ARRVAL_P(op);
- zend_string *key;
- zend_ulong num_key;
- zval *zv;
- ZEND_HASH_FOREACH_KEY_VAL(jumptable, num_key, key, zv) {
- if (key) {
- fprintf(stderr, " \"%s\":", ZSTR_VAL(key));
- } else {
- fprintf(stderr, " " ZEND_LONG_FMT ":", num_key);
- }
- if (b) {
- fprintf(stderr, " BB%d,", b->successors[n++]);
- } else {
- fprintf(stderr, " %04u,", (uint32_t)ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(zv)));
- }
- } ZEND_HASH_FOREACH_END();
- fprintf(stderr, " default:");
- } else {
- zend_dump_const(op);
- }
- } else if (opline->op2_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
- if (ssa_op) {
- int ssa_var_num = ssa_op->op2_use;
- if (ssa_var_num >= 0) {
- fprintf(stderr, " ");
- zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->op2_type, EX_VAR_TO_NUM(opline->op2.var), dump_flags);
- } else if (ssa_op->op2_def < 0) {
- fprintf(stderr, " ");
- zend_dump_var(op_array, opline->op2_type, EX_VAR_TO_NUM(opline->op2.var));
- }
- } else {
- fprintf(stderr, " ");
- zend_dump_var(op_array, opline->op2_type, EX_VAR_TO_NUM(opline->op2.var));
- }
- if (ssa_op) {
- int ssa_var_num = ssa_op->op2_def;
- if (ssa_var_num >= 0) {
- fprintf(stderr, " -> ");
- zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->op2_type, EX_VAR_TO_NUM(opline->op2.var), dump_flags);
- }
- }
- } else {
- uint32_t op2_flags = ZEND_VM_OP2_FLAGS(flags);
- if (ZEND_VM_OP_JMP_ADDR == (op2_flags & ZEND_VM_OP_MASK)) {
- if (opline->opcode != ZEND_CATCH || !(opline->extended_value & ZEND_LAST_CATCH)) {
- if (b) {
- fprintf(stderr, " BB%d", b->successors[n++]);
- } else {
- fprintf(stderr, " %04u", (uint32_t)(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes));
- }
- }
- } else {
- zend_dump_unused_op(opline, opline->op2, op2_flags);
- }
- }
- if (ZEND_VM_EXT_JMP_ADDR == (flags & ZEND_VM_EXT_MASK)) {
- if (b) {
- fprintf(stderr, " BB%d", b->successors[n++]);
- } else {
- fprintf(stderr, " %04u", (uint32_t)ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value));
- }
- }
- if (opline->result_type == IS_CONST) {
- zend_dump_const(CRT_CONSTANT(opline->result));
- #if 0
- } else if (opline->result_type & IS_SMART_BRANCH_JMPZ) {
- fprintf(stderr, " jmpz");
- } else if (opline->result_type & IS_SMART_BRANCH_JMPNZ) {
- fprintf(stderr, " jmpnz");
- #endif
- } else if (ssa_op && ssa_op->result_use >= 0) {
- if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
- if (ssa_op) {
- int ssa_var_num = ssa_op->result_use;
- if (ssa_var_num >= 0) {
- fprintf(stderr, " ");
- zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->result_type, EX_VAR_TO_NUM(opline->result.var), dump_flags);
- }
- } else {
- fprintf(stderr, " ");
- zend_dump_var(op_array, opline->result_type, EX_VAR_TO_NUM(opline->result.var));
- }
- if (ssa_op) {
- int ssa_var_num = ssa_op->result_def;
- if (ssa_var_num >= 0) {
- fprintf(stderr, " -> ");
- zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->result_type, EX_VAR_TO_NUM(opline->result.var), dump_flags);
- }
- }
- }
- }
- }
- ZEND_API void zend_dump_op_line(const zend_op_array *op_array, const zend_basic_block *b, const zend_op *opline, uint32_t dump_flags, const void *data)
- {
- int len = 0;
- const zend_ssa *ssa = NULL;
- zend_ssa_op *ssa_op = NULL;
-
- if (dump_flags & ZEND_DUMP_LINE_NUMBERS) {
- fprintf(stderr, "L%04u ", opline->lineno);
- }
- len = fprintf(stderr, "%04u", (uint32_t)(opline - op_array->opcodes));
- fprintf(stderr, "%*c", 5-len, ' ');
- if (dump_flags & ZEND_DUMP_SSA) {
- ssa = (const zend_ssa*)data;
- if (ssa && ssa->ops) {
- ssa_op = &ssa->ops[opline - op_array->opcodes];
- }
- }
- zend_dump_op(op_array, b, opline, dump_flags, ssa, ssa_op);
- fprintf(stderr, "\n");
- }
- static void zend_dump_block_info(const zend_cfg *cfg, int n, uint32_t dump_flags)
- {
- zend_basic_block *b = cfg->blocks + n;
- if (n > 0) {
- fprintf(stderr, "\n");
- }
- fprintf(stderr, "BB%d:\n ;", n);
- if (b->flags & ZEND_BB_START) {
- fprintf(stderr, " start");
- }
- if (b->flags & ZEND_BB_RECV_ENTRY) {
- fprintf(stderr, " recv");
- }
- if (b->flags & ZEND_BB_FOLLOW) {
- fprintf(stderr, " follow");
- }
- if (b->flags & ZEND_BB_TARGET) {
- fprintf(stderr, " target");
- }
- if (b->flags & ZEND_BB_EXIT) {
- fprintf(stderr, " exit");
- }
- if (b->flags & (ZEND_BB_ENTRY|ZEND_BB_RECV_ENTRY)) {
- fprintf(stderr, " entry");
- }
- if (b->flags & ZEND_BB_TRY) {
- fprintf(stderr, " try");
- }
- if (b->flags & ZEND_BB_CATCH) {
- fprintf(stderr, " catch");
- }
- if (b->flags & ZEND_BB_FINALLY) {
- fprintf(stderr, " finally");
- }
- if (b->flags & ZEND_BB_FINALLY_END) {
- fprintf(stderr, " finally_end");
- }
- if (!(dump_flags & ZEND_DUMP_HIDE_UNREACHABLE) && !(b->flags & ZEND_BB_REACHABLE)) {
- fprintf(stderr, " unreachable");
- }
- if (b->flags & ZEND_BB_UNREACHABLE_FREE) {
- fprintf(stderr, " unreachable_free");
- }
- if (b->flags & ZEND_BB_LOOP_HEADER) {
- fprintf(stderr, " loop_header");
- }
- if (b->flags & ZEND_BB_IRREDUCIBLE_LOOP) {
- fprintf(stderr, " irreducible");
- }
- if (b->len != 0) {
- fprintf(stderr, " lines=[%d-%d]", b->start, b->start + b->len - 1);
- } else {
- fprintf(stderr, " empty");
- }
- fprintf(stderr, "\n");
- if (b->predecessors_count) {
- int *p = cfg->predecessors + b->predecessor_offset;
- int *end = p + b->predecessors_count;
- fprintf(stderr, " ; from=(BB%d", *p);
- for (p++; p < end; p++) {
- fprintf(stderr, ", BB%d", *p);
- }
- fprintf(stderr, ")\n");
- }
- if (b->successors_count > 0) {
- int s;
- fprintf(stderr, " ; to=(BB%d", b->successors[0]);
- for (s = 1; s < b->successors_count; s++) {
- fprintf(stderr, ", BB%d", b->successors[s]);
- }
- fprintf(stderr, ")\n");
- }
- if (b->idom >= 0) {
- fprintf(stderr, " ; idom=BB%d\n", b->idom);
- }
- if (b->level >= 0) {
- fprintf(stderr, " ; level=%d\n", b->level);
- }
- if (b->loop_header >= 0) {
- fprintf(stderr, " ; loop_header=%d\n", b->loop_header);
- }
- if (b->children >= 0) {
- int j = b->children;
- fprintf(stderr, " ; children=(BB%d", j);
- j = cfg->blocks[j].next_child;
- while (j >= 0) {
- fprintf(stderr, ", BB%d", j);
- j = cfg->blocks[j].next_child;
- }
- fprintf(stderr, ")\n");
- }
- }
- static void zend_dump_block_header(const zend_cfg *cfg, const zend_op_array *op_array, const zend_ssa *ssa, int n, uint32_t dump_flags)
- {
- zend_dump_block_info(cfg, n, dump_flags);
- if (ssa && ssa->blocks && ssa->blocks[n].phis) {
- zend_ssa_phi *p = ssa->blocks[n].phis;
- do {
- int j;
- fprintf(stderr, " ");
- zend_dump_ssa_var(op_array, ssa, p->ssa_var, 0, p->var, dump_flags);
- if (p->pi < 0) {
- fprintf(stderr, " = Phi(");
- for (j = 0; j < cfg->blocks[n].predecessors_count; j++) {
- if (j > 0) {
- fprintf(stderr, ", ");
- }
- zend_dump_ssa_var(op_array, ssa, p->sources[j], 0, p->var, dump_flags);
- }
- fprintf(stderr, ")\n");
- } else {
- fprintf(stderr, " = Pi<BB%d>(", p->pi);
- zend_dump_ssa_var(op_array, ssa, p->sources[0], 0, p->var, dump_flags);
- fprintf(stderr, " &");
- if (p->has_range_constraint) {
- zend_dump_range_constraint(op_array, ssa, &p->constraint.range, dump_flags);
- } else {
- zend_dump_type_constraint(op_array, ssa, &p->constraint.type, dump_flags);
- }
- fprintf(stderr, ")\n");
- }
- p = p->next;
- } while (p);
- }
- }
- void zend_dump_op_array_name(const zend_op_array *op_array)
- {
- if (op_array->function_name) {
- if (op_array->scope && op_array->scope->name) {
- fprintf(stderr, "%s::%s", op_array->scope->name->val, op_array->function_name->val);
- } else {
- fprintf(stderr, "%s", op_array->function_name->val);
- }
- } else {
- fprintf(stderr, "%s", "$_main");
- }
- }
- ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, const char *msg, const void *data)
- {
- int i;
- const zend_cfg *cfg = NULL;
- const zend_ssa *ssa = NULL;
- zend_func_info *func_info = NULL;
- uint32_t func_flags = 0;
- if (dump_flags & (ZEND_DUMP_CFG|ZEND_DUMP_SSA)) {
- cfg = (const zend_cfg*)data;
- if (!cfg->blocks) {
- cfg = data = NULL;
- }
- }
- if (dump_flags & ZEND_DUMP_SSA) {
- ssa = (const zend_ssa*)data;
- }
- func_info = ZEND_FUNC_INFO(op_array);
- if (func_info) {
- func_flags = func_info->flags;
- }
- fprintf(stderr, "\n");
- zend_dump_op_array_name(op_array);
- fprintf(stderr, ":\n ; (lines=%d, args=%d",
- op_array->last,
- op_array->num_args);
- fprintf(stderr, ", vars=%d, tmps=%d", op_array->last_var, op_array->T);
- if (ssa) {
- fprintf(stderr, ", ssa_vars=%d", ssa->vars_count);
- }
- if (func_flags & ZEND_FUNC_INDIRECT_VAR_ACCESS) {
- fprintf(stderr, ", dynamic");
- }
- if (func_flags & ZEND_FUNC_RECURSIVE) {
- fprintf(stderr, ", recursive");
- if (func_flags & ZEND_FUNC_RECURSIVE_DIRECTLY) {
- fprintf(stderr, " directly");
- }
- if (func_flags & ZEND_FUNC_RECURSIVE_INDIRECTLY) {
- fprintf(stderr, " indirectly");
- }
- }
- if (func_flags & ZEND_FUNC_IRREDUCIBLE) {
- fprintf(stderr, ", irreducible");
- }
- if (func_flags & ZEND_FUNC_NO_LOOPS) {
- fprintf(stderr, ", no_loops");
- }
- if (func_flags & ZEND_FUNC_HAS_EXTENDED_STMT) {
- fprintf(stderr, ", extended_stmt");
- }
- if (func_flags & ZEND_FUNC_HAS_EXTENDED_FCALL) {
- fprintf(stderr, ", extended_fcall");
- }
- //TODO: this is useful only for JIT???
- #if 0
- if (info->flags & ZEND_JIT_FUNC_NO_IN_MEM_CVS) {
- fprintf(stderr, ", no_in_mem_cvs");
- }
- if (info->flags & ZEND_JIT_FUNC_NO_USED_ARGS) {
- fprintf(stderr, ", no_used_args");
- }
- if (info->flags & ZEND_JIT_FUNC_NO_SYMTAB) {
- fprintf(stderr, ", no_symtab");
- }
- if (info->flags & ZEND_JIT_FUNC_NO_FRAME) {
- fprintf(stderr, ", no_frame");
- }
- if (info->flags & ZEND_JIT_FUNC_INLINE) {
- fprintf(stderr, ", inline");
- }
- #endif
- fprintf(stderr, ")\n");
- if (msg) {
- fprintf(stderr, " ; (%s)\n", msg);
- }
- fprintf(stderr, " ; %s:%u-%u\n", op_array->filename->val, op_array->line_start, op_array->line_end);
- if (func_info) {
- fprintf(stderr, " ; return ");
- zend_dump_type_info(func_info->return_info.type, func_info->return_info.ce, func_info->return_info.is_instanceof, dump_flags);
- zend_dump_range(&func_info->return_info.range);
- fprintf(stderr, "\n");
- }
- if (ssa && ssa->var_info) {
- for (i = 0; i < op_array->last_var; i++) {
- fprintf(stderr, " ; ");
- zend_dump_ssa_var(op_array, ssa, i, IS_CV, i, dump_flags);
- fprintf(stderr, "\n");
- }
- }
- if (cfg) {
- int n;
- zend_basic_block *b;
- for (n = 0; n < cfg->blocks_count; n++) {
- b = cfg->blocks + n;
- if (!(dump_flags & ZEND_DUMP_HIDE_UNREACHABLE) || (b->flags & ZEND_BB_REACHABLE)) {
- const zend_op *opline;
- const zend_op *end;
- zend_dump_block_header(cfg, op_array, ssa, n, dump_flags);
- opline = op_array->opcodes + b->start;
- end = opline + b->len;
- while (opline < end) {
- zend_dump_op_line(op_array, b, opline, dump_flags, data);
- opline++;
- }
- }
- }
- if (op_array->last_live_range && (dump_flags & ZEND_DUMP_LIVE_RANGES)) {
- fprintf(stderr, "LIVE RANGES:\n");
- for (i = 0; i < op_array->last_live_range; i++) {
- fprintf(stderr,
- " %u: %04u - %04u ",
- EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK),
- op_array->live_range[i].start,
- op_array->live_range[i].end);
- switch (op_array->live_range[i].var & ZEND_LIVE_MASK) {
- case ZEND_LIVE_TMPVAR:
- fprintf(stderr, "(tmp/var)\n");
- break;
- case ZEND_LIVE_LOOP:
- fprintf(stderr, "(loop)\n");
- break;
- case ZEND_LIVE_SILENCE:
- fprintf(stderr, "(silence)\n");
- break;
- case ZEND_LIVE_ROPE:
- fprintf(stderr, "(rope)\n");
- break;
- case ZEND_LIVE_NEW:
- fprintf(stderr, "(new)\n");
- break;
- }
- }
- }
- if (op_array->last_try_catch) {
- fprintf(stderr, "EXCEPTION TABLE:\n");
- for (i = 0; i < op_array->last_try_catch; i++) {
- fprintf(stderr, " BB%u",
- cfg->map[op_array->try_catch_array[i].try_op]);
- if (op_array->try_catch_array[i].catch_op) {
- fprintf(stderr, ", BB%u",
- cfg->map[op_array->try_catch_array[i].catch_op]);
- } else {
- fprintf(stderr, ", -");
- }
- if (op_array->try_catch_array[i].finally_op) {
- fprintf(stderr, ", BB%u",
- cfg->map[op_array->try_catch_array[i].finally_op]);
- } else {
- fprintf(stderr, ", -");
- }
- if (op_array->try_catch_array[i].finally_end) {
- fprintf(stderr, ", BB%u\n",
- cfg->map[op_array->try_catch_array[i].finally_end]);
- } else {
- fprintf(stderr, ", -\n");
- }
- }
- }
- } else {
- const zend_op *opline = op_array->opcodes;
- const zend_op *end = opline + op_array->last;
- while (opline < end) {
- zend_dump_op_line(op_array, NULL, opline, dump_flags, data);
- opline++;
- }
- if (op_array->last_live_range && (dump_flags & ZEND_DUMP_LIVE_RANGES)) {
- fprintf(stderr, "LIVE RANGES:\n");
- for (i = 0; i < op_array->last_live_range; i++) {
- fprintf(stderr,
- " %u: %04u - %04u ",
- EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK),
- op_array->live_range[i].start,
- op_array->live_range[i].end);
- switch (op_array->live_range[i].var & ZEND_LIVE_MASK) {
- case ZEND_LIVE_TMPVAR:
- fprintf(stderr, "(tmp/var)\n");
- break;
- case ZEND_LIVE_LOOP:
- fprintf(stderr, "(loop)\n");
- break;
- case ZEND_LIVE_SILENCE:
- fprintf(stderr, "(silence)\n");
- break;
- case ZEND_LIVE_ROPE:
- fprintf(stderr, "(rope)\n");
- break;
- case ZEND_LIVE_NEW:
- fprintf(stderr, "(new)\n");
- break;
- }
- }
- }
- if (op_array->last_try_catch) {
- fprintf(stderr, "EXCEPTION TABLE:\n");
- for (i = 0; i < op_array->last_try_catch; i++) {
- fprintf(stderr,
- " %04u",
- op_array->try_catch_array[i].try_op);
- if (op_array->try_catch_array[i].catch_op) {
- fprintf(stderr,
- ", %04u",
- op_array->try_catch_array[i].catch_op);
- } else {
- fprintf(stderr, ", -");
- }
- if (op_array->try_catch_array[i].finally_op) {
- fprintf(stderr,
- ", %04u",
- op_array->try_catch_array[i].finally_op);
- } else {
- fprintf(stderr, ", -");
- }
- if (op_array->try_catch_array[i].finally_end) {
- fprintf(stderr,
- ", %04u",
- op_array->try_catch_array[i].finally_end);
- } else {
- fprintf(stderr, ", -\n");
- }
- }
- }
- }
- }
- void zend_dump_dominators(const zend_op_array *op_array, const zend_cfg *cfg)
- {
- int j;
- fprintf(stderr, "\nDOMINATORS-TREE for \"");
- zend_dump_op_array_name(op_array);
- fprintf(stderr, "\"\n");
- for (j = 0; j < cfg->blocks_count; j++) {
- zend_basic_block *b = cfg->blocks + j;
- if (b->flags & ZEND_BB_REACHABLE) {
- zend_dump_block_info(cfg, j, 0);
- }
- }
- }
- void zend_dump_variables(const zend_op_array *op_array)
- {
- int j;
- fprintf(stderr, "\nCV Variables for \"");
- zend_dump_op_array_name(op_array);
- fprintf(stderr, "\"\n");
- for (j = 0; j < op_array->last_var; j++) {
- fprintf(stderr, " ");
- zend_dump_var(op_array, IS_CV, j);
- fprintf(stderr, "\n");
- }
- }
- void zend_dump_ssa_variables(const zend_op_array *op_array, const zend_ssa *ssa, uint32_t dump_flags)
- {
- int j;
- if (ssa->vars) {
- fprintf(stderr, "\nSSA Variable for \"");
- zend_dump_op_array_name(op_array);
- fprintf(stderr, "\"\n");
- for (j = 0; j < ssa->vars_count; j++) {
- fprintf(stderr, " ");
- zend_dump_ssa_var(op_array, ssa, j, IS_CV, ssa->vars[j].var, dump_flags);
- if (ssa->vars[j].scc >= 0) {
- if (ssa->vars[j].scc_entry) {
- fprintf(stderr, " *");
- } else {
- fprintf(stderr, " ");
- }
- fprintf(stderr, "SCC=%d", ssa->vars[j].scc);
- }
- fprintf(stderr, "\n");
- }
- }
- }
- static void zend_dump_var_set(const zend_op_array *op_array, const char *name, zend_bitset set)
- {
- int first = 1;
- uint32_t i;
- fprintf(stderr, " ; %s = {", name);
- for (i = 0; i < op_array->last_var + op_array->T; i++) {
- if (zend_bitset_in(set, i)) {
- if (first) {
- first = 0;
- } else {
- fprintf(stderr, ", ");
- }
- zend_dump_var(op_array, IS_CV, i);
- }
- }
- fprintf(stderr, "}\n");
- }
- void zend_dump_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zend_dfg *dfg)
- {
- int j;
- fprintf(stderr, "\nVariable Liveness for \"");
- zend_dump_op_array_name(op_array);
- fprintf(stderr, "\"\n");
- for (j = 0; j < cfg->blocks_count; j++) {
- fprintf(stderr, " BB%d:\n", j);
- zend_dump_var_set(op_array, "def", DFG_BITSET(dfg->def, dfg->size, j));
- zend_dump_var_set(op_array, "use", DFG_BITSET(dfg->use, dfg->size, j));
- zend_dump_var_set(op_array, "in ", DFG_BITSET(dfg->in, dfg->size, j));
- zend_dump_var_set(op_array, "out", DFG_BITSET(dfg->out, dfg->size, j));
- }
- }
- void zend_dump_phi_placement(const zend_op_array *op_array, const zend_ssa *ssa)
- {
- int j;
- zend_ssa_block *ssa_blocks = ssa->blocks;
- int blocks_count = ssa->cfg.blocks_count;
- fprintf(stderr, "\nSSA Phi() Placement for \"");
- zend_dump_op_array_name(op_array);
- fprintf(stderr, "\"\n");
- for (j = 0; j < blocks_count; j++) {
- if (ssa_blocks && ssa_blocks[j].phis) {
- zend_ssa_phi *p = ssa_blocks[j].phis;
- int first = 1;
- fprintf(stderr, " BB%d:\n", j);
- if (p->pi >= 0) {
- fprintf(stderr, " ; pi={");
- } else {
- fprintf(stderr, " ; phi={");
- }
- do {
- if (first) {
- first = 0;
- } else {
- fprintf(stderr, ", ");
- }
- zend_dump_var(op_array, IS_CV, p->var);
- p = p->next;
- } while (p);
- fprintf(stderr, "}\n");
- }
- }
- }
|