PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/opcache/Optimizer - zend_dump.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 0 737 0.0 %
Date: 2017-10-15 Functions: 0 21 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine, Bytecode Visualisation                                  |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2017 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Dmitry Stogov <dmitry@zend.com>                             |
      16             :    +----------------------------------------------------------------------+
      17             : */
      18             : 
      19             : #include "php.h"
      20             : #include "zend_compile.h"
      21             : #include "zend_cfg.h"
      22             : #include "zend_ssa.h"
      23             : #include "zend_inference.h"
      24             : #include "zend_func_info.h"
      25             : #include "zend_call_graph.h"
      26             : #include "zend_dump.h"
      27             : 
      28           0 : static void zend_dump_const(const zval *zv)
      29             : {
      30           0 :         switch (Z_TYPE_P(zv)) {
      31             :                 case IS_NULL:
      32           0 :                         fprintf(stderr, " null");
      33           0 :                         break;
      34             :                 case IS_FALSE:
      35           0 :                         fprintf(stderr, " bool(false)");
      36           0 :                         break;
      37             :                 case IS_TRUE:
      38           0 :                         fprintf(stderr, " bool(true)");
      39           0 :                         break;
      40             :                 case IS_LONG:
      41           0 :                         fprintf(stderr, " int(" ZEND_LONG_FMT ")", Z_LVAL_P(zv));
      42           0 :                         break;
      43             :                 case IS_DOUBLE:
      44           0 :                         fprintf(stderr, " float(%g)", Z_DVAL_P(zv));
      45           0 :                         break;
      46             :                 case IS_STRING:
      47           0 :                         fprintf(stderr, " string(\"%s\")", Z_STRVAL_P(zv));
      48           0 :                         break;
      49             :                 case IS_ARRAY:
      50           0 :                         fprintf(stderr, " array(...)");
      51           0 :                         break;
      52             :                 default:
      53           0 :                         fprintf(stderr, " zval(type=%d)", Z_TYPE_P(zv));
      54             :                         break;
      55             :         }
      56           0 : }
      57             : 
      58           0 : static void zend_dump_class_fetch_type(uint32_t fetch_type)
      59             : {
      60           0 :         switch (fetch_type & ZEND_FETCH_CLASS_MASK) {
      61             :                 case ZEND_FETCH_CLASS_SELF:
      62           0 :                         fprintf(stderr, " (self)");
      63           0 :                         break;
      64             :                 case ZEND_FETCH_CLASS_PARENT:
      65           0 :                         fprintf(stderr, " (parent)");
      66           0 :                         break;
      67             :                 case ZEND_FETCH_CLASS_STATIC:
      68           0 :                         fprintf(stderr, " (static)");
      69           0 :                         break;
      70             :                 case ZEND_FETCH_CLASS_AUTO:
      71           0 :                         fprintf(stderr, " (auto)");
      72           0 :                         break;
      73             :                 case ZEND_FETCH_CLASS_INTERFACE:
      74           0 :                         fprintf(stderr, " (interface)");
      75           0 :                         break;
      76             :                 case ZEND_FETCH_CLASS_TRAIT:
      77           0 :                         fprintf(stderr, " (trait)");
      78             :                         break;
      79             :         }
      80           0 :         if (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) {
      81           0 :                         fprintf(stderr, " (no-autolod)");
      82             :         }
      83           0 :         if (fetch_type & ZEND_FETCH_CLASS_SILENT) {
      84           0 :                         fprintf(stderr, " (silent)");
      85             :         }
      86           0 :         if (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) {
      87           0 :                         fprintf(stderr, " (exception)");
      88             :         }
      89           0 : }
      90             : 
      91           0 : static void zend_dump_unused_op(const zend_op *opline, znode_op op, uint32_t flags) {
      92           0 :         if (ZEND_VM_OP_NUM == (flags & ZEND_VM_OP_MASK)) {
      93           0 :                 fprintf(stderr, " %u", op.num);
      94           0 :         } else if (ZEND_VM_OP_TRY_CATCH == (flags & ZEND_VM_OP_MASK)) {
      95           0 :                 if (op.num != (uint32_t)-1) {
      96           0 :                         fprintf(stderr, " try-catch(%u)", op.num);
      97             :                 }
      98           0 :         } else if (ZEND_VM_OP_LIVE_RANGE == (flags & ZEND_VM_OP_MASK)) {
      99           0 :                 if (opline->extended_value & ZEND_FREE_ON_RETURN) {
     100           0 :                         fprintf(stderr, " live-range(%u)", op.num);
     101             :                 }
     102           0 :         } else if (ZEND_VM_OP_THIS == (flags & ZEND_VM_OP_MASK)) {
     103           0 :                 fprintf(stderr, " THIS");
     104           0 :         } else if (ZEND_VM_OP_NEXT == (flags & ZEND_VM_OP_MASK)) {
     105           0 :                 fprintf(stderr, " NEXT");
     106           0 :         } else if (ZEND_VM_OP_CLASS_FETCH == (flags & ZEND_VM_OP_MASK)) {
     107           0 :                 zend_dump_class_fetch_type(op.num);
     108           0 :         } else if (ZEND_VM_OP_CONSTRUCTOR == (flags & ZEND_VM_OP_MASK)) {
     109           0 :                 fprintf(stderr, " CONSTRUCTOR");
     110             :         }
     111           0 : }
     112             : 
     113           0 : void zend_dump_var(const zend_op_array *op_array, zend_uchar var_type, int var_num)
     114             : {
     115           0 :         if (var_type == IS_CV && var_num < op_array->last_var) {
     116           0 :                 fprintf(stderr, "CV%d($%s)", var_num, op_array->vars[var_num]->val);
     117           0 :         } else if (var_type == IS_VAR) {
     118           0 :                 fprintf(stderr, "V%d", var_num);
     119           0 :         } else if (var_type == IS_TMP_VAR) {
     120           0 :                 fprintf(stderr, "T%d", var_num);
     121             :         } else {
     122           0 :                 fprintf(stderr, "X%d", var_num);
     123             :         }
     124           0 : }
     125             : 
     126           0 : static void zend_dump_range(const zend_ssa_range *r)
     127             : {
     128           0 :         if (r->underflow && r->overflow) {
     129           0 :                 return;
     130             :         }
     131           0 :         fprintf(stderr, " RANGE[");
     132           0 :         if (r->underflow) {
     133           0 :                 fprintf(stderr, "--..");
     134             :         } else {
     135           0 :                 fprintf(stderr, ZEND_LONG_FMT "..", r->min);
     136             :         }
     137           0 :         if (r->overflow) {
     138           0 :                 fprintf(stderr, "++]");
     139             :         } else {
     140           0 :                 fprintf(stderr, ZEND_LONG_FMT "]", r->max);
     141             :         }
     142             : }
     143             : 
     144           0 : static void zend_dump_type_info(uint32_t info, zend_class_entry *ce, int is_instanceof, uint32_t dump_flags)
     145             : {
     146           0 :         int first = 1;
     147             : 
     148           0 :         fprintf(stderr, " [");
     149           0 :         if (info & MAY_BE_UNDEF) {
     150           0 :                 if (first) first = 0; else fprintf(stderr, ", ");
     151           0 :                 fprintf(stderr, "undef");
     152             :         }
     153           0 :         if (info & MAY_BE_REF) {
     154           0 :                 if (first) first = 0; else fprintf(stderr, ", ");
     155           0 :                 fprintf(stderr, "ref");
     156             :         }
     157           0 :         if (dump_flags & ZEND_DUMP_RC_INFERENCE) {
     158           0 :                 if (info & MAY_BE_RC1) {
     159           0 :                         if (first) first = 0; else fprintf(stderr, ", ");
     160           0 :                         fprintf(stderr, "rc1");
     161             :                 }
     162           0 :                 if (info & MAY_BE_RCN) {
     163           0 :                         if (first) first = 0; else fprintf(stderr, ", ");
     164           0 :                         fprintf(stderr, "rcn");
     165             :                 }
     166             :         }
     167           0 :         if (info & MAY_BE_CLASS) {
     168           0 :                 if (first) first = 0; else fprintf(stderr, ", ");
     169           0 :                 fprintf(stderr, "class");
     170           0 :                 if (ce) {
     171           0 :                         if (is_instanceof) {
     172           0 :                                 fprintf(stderr, " (instanceof %s)", ce->name->val);
     173             :                         } else {
     174           0 :                                 fprintf(stderr, " (%s)", ce->name->val);
     175             :                         }
     176             :                 }
     177           0 :         } else if ((info & MAY_BE_ANY) == MAY_BE_ANY) {
     178           0 :                 if (first) first = 0; else fprintf(stderr, ", ");
     179           0 :                 fprintf(stderr, "any");
     180             :         } else {
     181           0 :                 if (info & MAY_BE_NULL) {
     182           0 :                         if (first) first = 0; else fprintf(stderr, ", ");
     183           0 :                         fprintf(stderr, "null");
     184             :                 }
     185           0 :                 if ((info & MAY_BE_FALSE) && (info & MAY_BE_TRUE)) {
     186           0 :                         if (first) first = 0; else fprintf(stderr, ", ");
     187           0 :                         fprintf(stderr, "bool");
     188           0 :                 } else if (info & MAY_BE_FALSE) {
     189           0 :                         if (first) first = 0; else fprintf(stderr, ", ");
     190           0 :                         fprintf(stderr, "false");
     191           0 :                 } else if (info & MAY_BE_TRUE) {
     192           0 :                         if (first) first = 0; else fprintf(stderr, ", ");
     193           0 :                         fprintf(stderr, "true");
     194             :                 }
     195           0 :                 if (info & MAY_BE_LONG) {
     196           0 :                         if (first) first = 0; else fprintf(stderr, ", ");
     197           0 :                         fprintf(stderr, "long");
     198             :                 }
     199           0 :                 if (info & MAY_BE_DOUBLE) {
     200           0 :                         if (first) first = 0; else fprintf(stderr, ", ");
     201           0 :                         fprintf(stderr, "double");
     202             :                 }
     203           0 :                 if (info & MAY_BE_STRING) {
     204           0 :                         if (first) first = 0; else fprintf(stderr, ", ");
     205           0 :                         fprintf(stderr, "string");
     206             :                 }
     207           0 :                 if (info & MAY_BE_ARRAY) {
     208           0 :                         if (first) first = 0; else fprintf(stderr, ", ");
     209           0 :                         fprintf(stderr, "array");
     210           0 :                         if ((info & MAY_BE_ARRAY_KEY_ANY) != 0 &&
     211           0 :                             (info & MAY_BE_ARRAY_KEY_ANY) != MAY_BE_ARRAY_KEY_ANY) {
     212           0 :                                 int afirst = 1;
     213           0 :                                 fprintf(stderr, " [");
     214           0 :                                 if (info & MAY_BE_ARRAY_KEY_LONG) {
     215           0 :                                         if (afirst) afirst = 0; else fprintf(stderr, ", ");
     216           0 :                                         fprintf(stderr, "long");
     217             :                                 }
     218           0 :                                 if (info & MAY_BE_ARRAY_KEY_STRING) {
     219           0 :                                         if (afirst) afirst = 0; else fprintf(stderr, ", ");
     220           0 :                                                 fprintf(stderr, "string");
     221             :                                         }
     222           0 :                                 fprintf(stderr, "]");
     223             :                         }
     224           0 :                         if (info & (MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF)) {
     225           0 :                                 int afirst = 1;
     226           0 :                                 fprintf(stderr, " of [");
     227           0 :                                 if ((info & MAY_BE_ARRAY_OF_ANY) == MAY_BE_ARRAY_OF_ANY) {
     228           0 :                                         if (afirst) afirst = 0; else fprintf(stderr, ", ");
     229           0 :                                         fprintf(stderr, "any");
     230             :                                 } else {
     231           0 :                                         if (info & MAY_BE_ARRAY_OF_NULL) {
     232           0 :                                                 if (afirst) afirst = 0; else fprintf(stderr, ", ");
     233           0 :                                                 fprintf(stderr, "null");
     234             :                                         }
     235           0 :                                         if (info & MAY_BE_ARRAY_OF_FALSE) {
     236           0 :                                                 if (afirst) afirst = 0; else fprintf(stderr, ", ");
     237           0 :                                                 fprintf(stderr, "false");
     238             :                                         }
     239           0 :                                         if (info & MAY_BE_ARRAY_OF_TRUE) {
     240           0 :                                                 if (afirst) afirst = 0; else fprintf(stderr, ", ");
     241           0 :                                                 fprintf(stderr, "true");
     242             :                                         }
     243           0 :                                         if (info & MAY_BE_ARRAY_OF_LONG) {
     244           0 :                                                 if (afirst) afirst = 0; else fprintf(stderr, ", ");
     245           0 :                                                 fprintf(stderr, "long");
     246             :                                         }
     247           0 :                                         if (info & MAY_BE_ARRAY_OF_DOUBLE) {
     248           0 :                                                 if (afirst) afirst = 0; else fprintf(stderr, ", ");
     249           0 :                                                 fprintf(stderr, "double");
     250             :                                         }
     251           0 :                                         if (info & MAY_BE_ARRAY_OF_STRING) {
     252           0 :                                                 if (afirst) afirst = 0; else fprintf(stderr, ", ");
     253           0 :                                                 fprintf(stderr, "string");
     254             :                                         }
     255           0 :                                         if (info & MAY_BE_ARRAY_OF_ARRAY) {
     256           0 :                                                 if (afirst) afirst = 0; else fprintf(stderr, ", ");
     257           0 :                                                 fprintf(stderr, "array");
     258             :                                         }
     259           0 :                                         if (info & MAY_BE_ARRAY_OF_OBJECT) {
     260           0 :                                                 if (afirst) afirst = 0; else fprintf(stderr, ", ");
     261           0 :                                                 fprintf(stderr, "object");
     262             :                                         }
     263           0 :                                         if (info & MAY_BE_ARRAY_OF_RESOURCE) {
     264           0 :                                                 if (afirst) afirst = 0; else fprintf(stderr, ", ");
     265           0 :                                                 fprintf(stderr, "resource");
     266             :                                         }
     267             :                                 }
     268           0 :                                 if (info & MAY_BE_ARRAY_OF_REF) {
     269           0 :                                         if (afirst) afirst = 0; else fprintf(stderr, ", ");
     270           0 :                                         fprintf(stderr, "ref");
     271             :                                 }
     272           0 :                                 fprintf(stderr, "]");
     273             :                         }
     274             :                 }
     275           0 :                 if (info & MAY_BE_OBJECT) {
     276           0 :                         if (first) first = 0; else fprintf(stderr, ", ");
     277           0 :                         fprintf(stderr, "object");
     278           0 :                         if (ce) {
     279           0 :                                 if (is_instanceof) {
     280           0 :                                         fprintf(stderr, " (instanceof %s)", ce->name->val);
     281             :                                 } else {
     282           0 :                                         fprintf(stderr, " (%s)", ce->name->val);
     283             :                                 }
     284             :                         }
     285             :                 }
     286           0 :                 if (info & MAY_BE_RESOURCE) {
     287           0 :                         if (first) first = 0; else fprintf(stderr, ", ");
     288           0 :                         fprintf(stderr, "resource");
     289             :                 }
     290             :         }
     291           0 :         if (info & MAY_BE_ERROR) {
     292           0 :                 if (first) first = 0; else fprintf(stderr, ", ");
     293           0 :                 fprintf(stderr, "error");
     294             :         }
     295             : //TODO: this is useful only for JIT???
     296           0 :         if (info & MAY_BE_IN_REG) {
     297           0 :                 if (first) first = 0; else fprintf(stderr, ", ");
     298           0 :                 fprintf(stderr, "reg");
     299             :         }
     300           0 :         fprintf(stderr, "]");
     301           0 : }
     302             : 
     303           0 : static void zend_dump_ssa_var_info(const zend_ssa *ssa, int ssa_var_num, uint32_t dump_flags)
     304             : {
     305           0 :         zend_dump_type_info(
     306           0 :                 ssa->var_info[ssa_var_num].type,
     307           0 :                 ssa->var_info[ssa_var_num].ce,
     308           0 :                 ssa->var_info[ssa_var_num].ce ?
     309           0 :                         ssa->var_info[ssa_var_num].is_instanceof : 0,
     310             :                 dump_flags);
     311           0 : }
     312             : 
     313           0 : static 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)
     314             : {
     315           0 :         if (ssa_var_num >= 0) {
     316           0 :                 fprintf(stderr, "#%d.", ssa_var_num);
     317             :         } else {
     318           0 :                 fprintf(stderr, "#?.");
     319             :         }
     320           0 :         zend_dump_var(op_array, (var_num < op_array->last_var ? IS_CV : var_type), var_num);
     321             : 
     322           0 :         if (ssa_var_num >= 0 && ssa->vars) {
     323           0 :                 if (ssa_var_num >= 0 && ssa->vars[ssa_var_num].no_val) {
     324           0 :                         fprintf(stderr, " NOVAL");
     325             :                 }
     326           0 :                 if (ssa->var_info) {
     327           0 :                         zend_dump_ssa_var_info(ssa, ssa_var_num, dump_flags);
     328           0 :                         if (ssa->var_info[ssa_var_num].has_range) {
     329           0 :                                 zend_dump_range(&ssa->var_info[ssa_var_num].range);
     330             :                         }
     331             :                 }
     332             :         }
     333           0 : }
     334             : 
     335           0 : 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)
     336             : {
     337           0 :         fprintf(stderr, " TYPE");
     338           0 :         zend_dump_type_info(constraint->type_mask, constraint->ce, 1, dump_flags);
     339           0 : }
     340             : 
     341           0 : 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)
     342             : {
     343           0 :         if (r->range.underflow && r->range.overflow) {
     344           0 :                 return;
     345             :         }
     346           0 :         fprintf(stderr, " RANGE");
     347           0 :         if (r->negative) {
     348           0 :                 fprintf(stderr, "~");
     349             :         }
     350           0 :         fprintf(stderr, "[");
     351           0 :         if (r->range.underflow) {
     352           0 :                 fprintf(stderr, "-- .. ");
     353             :         } else {
     354           0 :                 if (r->min_ssa_var >= 0) {
     355           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);
     356           0 :                         if (r->range.min > 0) {
     357           0 :                                 fprintf(stderr, " + " ZEND_LONG_FMT, r->range.min);
     358           0 :                         } else if (r->range.min < 0) {
     359           0 :                                 fprintf(stderr, " - " ZEND_LONG_FMT, -r->range.min);
     360             :                         }
     361           0 :                         fprintf(stderr, " .. ");
     362             :                 } else {
     363           0 :                         fprintf(stderr, ZEND_LONG_FMT " .. ", r->range.min);
     364             :                 }
     365             :         }
     366           0 :         if (r->range.overflow) {
     367           0 :                 fprintf(stderr, "++]");
     368             :         } else {
     369           0 :                 if (r->max_ssa_var >= 0) {
     370           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);
     371           0 :                         if (r->range.max > 0) {
     372           0 :                                 fprintf(stderr, " + " ZEND_LONG_FMT, r->range.max);
     373           0 :                         } else if (r->range.max < 0) {
     374           0 :                                 fprintf(stderr, " - " ZEND_LONG_FMT, -r->range.max);
     375             :                         }
     376           0 :                         fprintf(stderr, "]");
     377             :                 } else {
     378           0 :                         fprintf(stderr, ZEND_LONG_FMT "]", r->range.max);
     379             :                 }
     380             :         }
     381             : }
     382             : 
     383           0 : 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)
     384             : {
     385           0 :         const char *name = zend_get_opcode_name(opline->opcode);
     386           0 :         uint32_t flags = zend_get_opcode_flags(opline->opcode);
     387           0 :         uint32_t n = 0;
     388           0 :         int len = 0;
     389           0 :         const zend_ssa *ssa = NULL;
     390             : 
     391           0 :         if (dump_flags & ZEND_DUMP_SSA) {
     392           0 :                 ssa = (const zend_ssa*)data;
     393             :         }
     394             : 
     395           0 :         if (!b) {
     396           0 :                 len = fprintf(stderr, "L%u:", (uint32_t)(opline - op_array->opcodes));
     397             :         }
     398           0 :         fprintf(stderr, "%*c", 8-len, ' ');
     399             : 
     400           0 :         if (!ssa || !ssa->ops || ssa->ops[opline - op_array->opcodes].result_use < 0) {
     401           0 :                 if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
     402           0 :                         if (ssa && ssa->ops && ssa->ops[opline - op_array->opcodes].result_def >= 0) {
     403           0 :                                 int ssa_var_num = ssa->ops[opline - op_array->opcodes].result_def;
     404           0 :                                 zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->result_type, EX_VAR_TO_NUM(opline->result.var), dump_flags);
     405             :                         } else {
     406           0 :                                 zend_dump_var(op_array, opline->result_type, EX_VAR_TO_NUM(opline->result.var));
     407             :                         }
     408           0 :                         fprintf(stderr, " = ");
     409             :                 }
     410             :         }
     411             : 
     412           0 :         if (name) {
     413           0 :                 fprintf(stderr, "%s", (name + 5));
     414             :         } else {
     415           0 :                 fprintf(stderr, "OP_%d", (int)opline->opcode);
     416             :         }
     417             : 
     418           0 :         if (ZEND_VM_EXT_NUM == (flags & ZEND_VM_EXT_MASK)) {
     419           0 :                 fprintf(stderr, " %u", opline->extended_value);
     420           0 :         } else if (ZEND_VM_EXT_DIM_OBJ == (flags & ZEND_VM_EXT_MASK)) {
     421           0 :                 if (opline->extended_value == ZEND_ASSIGN_DIM) {
     422           0 :                         fprintf(stderr, " (dim)");
     423           0 :                 } else if (opline->extended_value == ZEND_ASSIGN_OBJ) {
     424           0 :                         fprintf(stderr, " (obj)");
     425             :                 }
     426           0 :         } else if (ZEND_VM_EXT_CLASS_FETCH == (flags & ZEND_VM_EXT_MASK)) {
     427           0 :                 zend_dump_class_fetch_type(opline->extended_value);
     428           0 :         } else if (ZEND_VM_EXT_CONST_FETCH == (flags & ZEND_VM_EXT_MASK)) {
     429           0 :                 if (opline->extended_value & IS_CONSTANT_UNQUALIFIED) {
     430           0 :                                 fprintf(stderr, " (unqualified)");
     431             :                 }
     432           0 :                 if (opline->extended_value & IS_CONSTANT_CLASS) {
     433           0 :                                 fprintf(stderr, " (__class__)");
     434             :                 }
     435           0 :                 if (opline->extended_value & IS_CONSTANT_IN_NAMESPACE) {
     436           0 :                                 fprintf(stderr, " (in-namespace)");
     437             :                 }
     438           0 :         } else if (ZEND_VM_EXT_TYPE == (flags & ZEND_VM_EXT_MASK)) {
     439           0 :                 switch (opline->extended_value) {
     440             :                         case IS_NULL:
     441           0 :                                 fprintf(stderr, " (null)");
     442           0 :                                 break;
     443             :                         case IS_FALSE:
     444           0 :                                 fprintf(stderr, " (false)");
     445           0 :                                 break;
     446             :                         case IS_TRUE:
     447           0 :                                 fprintf(stderr, " (true)");
     448           0 :                                 break;
     449             :                         case IS_LONG:
     450           0 :                                 fprintf(stderr, " (long)");
     451           0 :                                 break;
     452             :                         case IS_DOUBLE:
     453           0 :                                 fprintf(stderr, " (double)");
     454           0 :                                 break;
     455             :                         case IS_STRING:
     456           0 :                                 fprintf(stderr, " (string)");
     457           0 :                                 break;
     458             :                         case IS_ARRAY:
     459           0 :                                 fprintf(stderr, " (array)");
     460           0 :                                 break;
     461             :                         case IS_OBJECT:
     462           0 :                                 fprintf(stderr, " (object)");
     463           0 :                                 break;
     464             :                         case IS_RESOURCE:
     465           0 :                                 fprintf(stderr, " (resource)");
     466           0 :                                 break;
     467             :                         case _IS_BOOL:
     468           0 :                                 fprintf(stderr, " (bool)");
     469           0 :                                 break;
     470             :                         case IS_CALLABLE:
     471           0 :                                 fprintf(stderr, " (callable)");
     472           0 :                                 break;
     473             :                         case IS_VOID:
     474           0 :                                 fprintf(stderr, " (void)");
     475           0 :                                 break;
     476             :                         default:
     477           0 :                                 fprintf(stderr, " (\?\?\?)");
     478             :                                 break;
     479             :                 }
     480           0 :         } else if (ZEND_VM_EXT_EVAL == (flags & ZEND_VM_EXT_MASK)) {
     481           0 :                 switch (opline->extended_value) {
     482             :                         case ZEND_EVAL:
     483           0 :                                 fprintf(stderr, " (eval)");
     484           0 :                                 break;
     485             :                         case ZEND_INCLUDE:
     486           0 :                                 fprintf(stderr, " (include)");
     487           0 :                                 break;
     488             :                         case ZEND_INCLUDE_ONCE:
     489           0 :                                 fprintf(stderr, " (include_once)");
     490           0 :                                 break;
     491             :                         case ZEND_REQUIRE:
     492           0 :                                 fprintf(stderr, " (require)");
     493           0 :                                 break;
     494             :                         case ZEND_REQUIRE_ONCE:
     495           0 :                                 fprintf(stderr, " (require_once)");
     496           0 :                                 break;
     497             :                         default:
     498           0 :                                 fprintf(stderr, " (\?\?\?)");
     499             :                                 break;
     500             :                 }
     501           0 :         } else if (ZEND_VM_EXT_SRC == (flags & ZEND_VM_EXT_MASK)) {
     502           0 :                 if (opline->extended_value == ZEND_RETURNS_VALUE) {
     503           0 :                         fprintf(stderr, " (value)");
     504           0 :                 } else if (opline->extended_value == ZEND_RETURNS_FUNCTION) {
     505           0 :                         fprintf(stderr, " (function)");
     506             :                 }
     507             :         } else {
     508           0 :                 if (ZEND_VM_EXT_VAR_FETCH & flags) {
     509           0 :                         switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
     510             :                                 case ZEND_FETCH_GLOBAL:
     511           0 :                                         fprintf(stderr, " (global)");
     512           0 :                                         break;
     513             :                                 case ZEND_FETCH_LOCAL:
     514           0 :                                         fprintf(stderr, " (local)");
     515           0 :                                         break;
     516             :                                 case ZEND_FETCH_GLOBAL_LOCK:
     517           0 :                                         fprintf(stderr, " (global+lock)");
     518             :                                         break;
     519             :                         }
     520             :                 }
     521           0 :                 if (ZEND_VM_EXT_ISSET & flags) {
     522           0 :                     if (opline->extended_value & ZEND_QUICK_SET) {
     523           0 :                                 fprintf(stderr, " (quick)");
     524             :                     }
     525           0 :                         if (opline->extended_value & ZEND_ISSET) {
     526           0 :                                 fprintf(stderr, " (isset)");
     527           0 :                         } else if (opline->extended_value & ZEND_ISEMPTY) {
     528           0 :                                 fprintf(stderr, " (empty)");
     529             :                         }
     530             :                 }
     531           0 :                 if (ZEND_VM_EXT_ARG_NUM & flags) {
     532           0 :                         fprintf(stderr, " %u", opline->extended_value & ZEND_FETCH_ARG_MASK);
     533             :                 }
     534           0 :                 if (ZEND_VM_EXT_ARRAY_INIT & flags) {
     535           0 :                         fprintf(stderr, " %u", opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT);
     536           0 :                         if (!(opline->extended_value & ZEND_ARRAY_NOT_PACKED)) {
     537           0 :                                 fprintf(stderr, " (packed)");
     538             :                         }
     539             :                 }
     540           0 :                 if (ZEND_VM_EXT_REF & flags) {
     541           0 :                         if (opline->extended_value & ZEND_ARRAY_ELEMENT_REF) {
     542           0 :                                 fprintf(stderr, " (ref)");
     543             :                         }
     544             :                 }
     545             :         }
     546             : 
     547           0 :         if (opline->op1_type == IS_CONST) {
     548           0 :                 zend_dump_const(CRT_CONSTANT_EX(op_array, opline->op1, (dump_flags & ZEND_DUMP_RT_CONSTANTS)));
     549           0 :         } else if (opline->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
     550           0 :                 if (ssa && ssa->ops) {
     551           0 :                         int ssa_var_num = ssa->ops[opline - op_array->opcodes].op1_use;
     552           0 :                         if (ssa_var_num >= 0) {
     553           0 :                                 fprintf(stderr, " ");
     554           0 :                                 zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->op1_type, EX_VAR_TO_NUM(opline->op1.var), dump_flags);
     555           0 :                         } else if (ssa->ops[opline - op_array->opcodes].op1_def < 0) {
     556           0 :                                 fprintf(stderr, " ");
     557           0 :                                 zend_dump_var(op_array, opline->op1_type, EX_VAR_TO_NUM(opline->op1.var));
     558             :                         }
     559             :                 } else {
     560           0 :                         fprintf(stderr, " ");
     561           0 :                         zend_dump_var(op_array, opline->op1_type, EX_VAR_TO_NUM(opline->op1.var));
     562             :                 }
     563           0 :                 if (ssa && ssa->ops) {
     564           0 :                         int ssa_var_num = ssa->ops[opline - op_array->opcodes].op1_def;
     565           0 :                         if (ssa_var_num >= 0) {
     566           0 :                                 fprintf(stderr, " -> ");
     567           0 :                                 zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->op1_type, EX_VAR_TO_NUM(opline->op1.var), dump_flags);
     568             :                         }
     569             :                 }
     570             :         } else {
     571           0 :                 uint32_t op1_flags = ZEND_VM_OP1_FLAGS(flags);
     572           0 :                 if (ZEND_VM_OP_JMP_ADDR == (op1_flags & ZEND_VM_OP_MASK)) {
     573           0 :                         if (b) {
     574           0 :                                 fprintf(stderr, " BB%d", b->successors[n++]);
     575             :                         } else {
     576           0 :                                 fprintf(stderr, " L%u", (uint32_t)(OP_JMP_ADDR(opline, opline->op1) - op_array->opcodes));
     577             :                         }
     578             :                 } else {
     579           0 :                         zend_dump_unused_op(opline, opline->op1, op1_flags);
     580             :                 }
     581             :         }
     582             : 
     583           0 :         if (opline->op2_type == IS_CONST) {
     584           0 :                 zend_dump_const(CRT_CONSTANT_EX(op_array, opline->op2, (dump_flags & ZEND_DUMP_RT_CONSTANTS)));
     585           0 :         } else if (opline->op2_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
     586           0 :                 if (ssa && ssa->ops) {
     587           0 :                         int ssa_var_num = ssa->ops[opline - op_array->opcodes].op2_use;
     588           0 :                         if (ssa_var_num >= 0) {
     589           0 :                                 fprintf(stderr, " ");
     590           0 :                                 zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->op2_type, EX_VAR_TO_NUM(opline->op2.var), dump_flags);
     591           0 :                         } else if (ssa->ops[opline - op_array->opcodes].op2_def < 0) {
     592           0 :                                 fprintf(stderr, " ");
     593           0 :                                 zend_dump_var(op_array, opline->op2_type, EX_VAR_TO_NUM(opline->op2.var));
     594             :                         }
     595             :                 } else {
     596           0 :                         fprintf(stderr, " ");
     597           0 :                         zend_dump_var(op_array, opline->op2_type, EX_VAR_TO_NUM(opline->op2.var));
     598             :                 }
     599           0 :                 if (ssa && ssa->ops) {
     600           0 :                         int ssa_var_num = ssa->ops[opline - op_array->opcodes].op2_def;
     601           0 :                         if (ssa_var_num >= 0) {
     602           0 :                                 fprintf(stderr, " -> ");
     603           0 :                                 zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->op2_type, EX_VAR_TO_NUM(opline->op2.var), dump_flags);
     604             :                         }
     605             :                 }
     606             :         } else {
     607           0 :                 uint32_t op2_flags = ZEND_VM_OP2_FLAGS(flags);
     608           0 :                 if (ZEND_VM_OP_JMP_ADDR == (op2_flags & ZEND_VM_OP_MASK)) {
     609           0 :                         if (b) {
     610           0 :                                 fprintf(stderr, " BB%d", b->successors[n++]);
     611             :                         } else {
     612           0 :                                 fprintf(stderr, " L%u", (uint32_t)(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes));
     613             :                         }
     614             :                 } else {
     615           0 :                         zend_dump_unused_op(opline, opline->op2, op2_flags);
     616             :                 }
     617             :         }
     618             : 
     619           0 :         if (ZEND_VM_EXT_JMP_ADDR == (flags & ZEND_VM_EXT_MASK)) {
     620           0 :                 if (opline->opcode != ZEND_CATCH || !opline->result.num) {
     621           0 :                         if (b) {
     622           0 :                                 fprintf(stderr, " BB%d", b->successors[n++]);
     623             :                         } else {
     624           0 :                                 fprintf(stderr, " L%u", (uint32_t)ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value));
     625             :                         }
     626             :                 }
     627             :         }
     628           0 :         if (opline->result_type == IS_CONST) {
     629           0 :                 zend_dump_const(CRT_CONSTANT_EX(op_array, opline->result, (dump_flags & ZEND_DUMP_RT_CONSTANTS)));
     630           0 :         } else if (ssa && ssa->ops && ssa->ops[opline - op_array->opcodes].result_use >= 0) {
     631           0 :                 if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
     632           0 :                         if (ssa && ssa->ops) {
     633           0 :                                 int ssa_var_num = ssa->ops[opline - op_array->opcodes].result_use;
     634           0 :                                 if (ssa_var_num >= 0) {
     635           0 :                                         fprintf(stderr, " ");
     636           0 :                                         zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->result_type, EX_VAR_TO_NUM(opline->result.var), dump_flags);
     637             :                                 }
     638             :                         } else {
     639           0 :                                 fprintf(stderr, " ");
     640           0 :                                 zend_dump_var(op_array, opline->result_type, EX_VAR_TO_NUM(opline->result.var));
     641             :                         }
     642           0 :                         if (ssa && ssa->ops) {
     643           0 :                                 int ssa_var_num = ssa->ops[opline - op_array->opcodes].result_def;
     644           0 :                                 if (ssa_var_num >= 0) {
     645           0 :                                         fprintf(stderr, " -> ");
     646           0 :                                         zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->result_type, EX_VAR_TO_NUM(opline->result.var), dump_flags);
     647             :                                 }
     648             :                         }
     649             :                 }
     650             :         }
     651           0 :         fprintf(stderr, "\n");
     652           0 : }
     653             : 
     654           0 : static void zend_dump_block_info(const zend_cfg *cfg, int n, uint32_t dump_flags)
     655             : {
     656           0 :         zend_basic_block *b = cfg->blocks + n;
     657           0 :         int printed = 0;
     658             : 
     659           0 :         fprintf(stderr, "BB%d:", n);
     660           0 :         if (b->flags & ZEND_BB_START) {
     661           0 :                 fprintf(stderr, " start");
     662             :         }
     663           0 :         if (b->flags & ZEND_BB_FOLLOW) {
     664           0 :                 fprintf(stderr, " follow");
     665             :         }
     666           0 :         if (b->flags & ZEND_BB_TARGET) {
     667           0 :                 fprintf(stderr, " target");
     668             :         }
     669           0 :         if (b->flags & ZEND_BB_EXIT) {
     670           0 :                 fprintf(stderr, " exit");
     671             :         }
     672           0 :         if (b->flags & (ZEND_BB_ENTRY|ZEND_BB_RECV_ENTRY)) {
     673           0 :                 fprintf(stderr, " entry");
     674             :         }
     675           0 :         if (b->flags & ZEND_BB_TRY) {
     676           0 :                 fprintf(stderr, " try");
     677             :         }
     678           0 :         if (b->flags & ZEND_BB_CATCH) {
     679           0 :                 fprintf(stderr, " catch");
     680             :         }
     681           0 :         if (b->flags & ZEND_BB_FINALLY) {
     682           0 :                 fprintf(stderr, " finally");
     683             :         }
     684           0 :         if (b->flags & ZEND_BB_FINALLY_END) {
     685           0 :                 fprintf(stderr, " finally_end");
     686             :         }
     687           0 :         if (b->flags & ZEND_BB_GEN_VAR) {
     688           0 :                 fprintf(stderr, " gen_var");
     689             :         }
     690           0 :         if (b->flags & ZEND_BB_KILL_VAR) {
     691           0 :                 fprintf(stderr, " kill_var");
     692             :         }
     693           0 :         if (!(dump_flags & ZEND_DUMP_HIDE_UNREACHABLE) && !(b->flags & ZEND_BB_REACHABLE)) {
     694           0 :                 fprintf(stderr, " unreachable");
     695             :         }
     696           0 :         if (b->flags & ZEND_BB_LOOP_HEADER) {
     697           0 :                 fprintf(stderr, " loop_header");
     698             :         }
     699           0 :         if (b->flags & ZEND_BB_IRREDUCIBLE_LOOP) {
     700           0 :                 fprintf(stderr, " irreducible");
     701             :         }
     702           0 :         if (b->len != 0) {
     703           0 :                 fprintf(stderr, " lines=[%d-%d]", b->start, b->start + b->len - 1);
     704             :         } else {
     705           0 :                 fprintf(stderr, " empty");
     706             :         }
     707           0 :         fprintf(stderr, "\n");
     708             : 
     709           0 :         if (b->predecessors_count) {
     710           0 :                 int *p = cfg->predecessors + b->predecessor_offset;
     711           0 :                 int *end = p + b->predecessors_count;
     712             : 
     713           0 :                 fprintf(stderr, "    ; from=(BB%d", *p);
     714           0 :                 for (p++; p < end; p++) {
     715           0 :                         fprintf(stderr, ", BB%d", *p);
     716             :                 }
     717           0 :                 fprintf(stderr, ")\n");
     718             :         }
     719             : 
     720           0 :         if (b->successors[0] != -1) {
     721           0 :                 fprintf(stderr, "    ; to=(BB%d", b->successors[0]);
     722           0 :                 printed = 1;
     723           0 :                 if (b->successors[1] != -1) {
     724           0 :                         fprintf(stderr, ", BB%d", b->successors[1]);
     725             :                 }
     726             :         }
     727           0 :         if (printed) {
     728           0 :                 fprintf(stderr, ")\n");
     729             :         }
     730             : 
     731           0 :         if (b->idom >= 0) {
     732           0 :                 fprintf(stderr, "    ; idom=BB%d\n", b->idom);
     733             :         }
     734           0 :         if (b->level >= 0) {
     735           0 :                 fprintf(stderr, "    ; level=%d\n", b->level);
     736             :         }
     737           0 :         if (b->loop_header >= 0) {
     738           0 :                 fprintf(stderr, "    ; loop_header=%d\n", b->loop_header);
     739             :         }
     740           0 :         if (b->children >= 0) {
     741           0 :                 int j = b->children;
     742           0 :                 fprintf(stderr, "    ; children=(BB%d", j);
     743           0 :                 j = cfg->blocks[j].next_child;
     744           0 :                 while (j >= 0) {
     745           0 :                         fprintf(stderr, ", BB%d", j);
     746           0 :                         j = cfg->blocks[j].next_child;
     747             :                 }
     748           0 :                 fprintf(stderr, ")\n");
     749             :         }
     750           0 : }
     751             : 
     752           0 : 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)
     753             : {
     754           0 :         zend_dump_block_info(cfg, n, dump_flags);
     755           0 :         if (ssa && ssa->blocks && ssa->blocks[n].phis) {
     756           0 :                 zend_ssa_phi *p = ssa->blocks[n].phis;
     757             : 
     758             :                 do {
     759             :                         int j;
     760             : 
     761           0 :                         fprintf(stderr, "        ");
     762           0 :                         zend_dump_ssa_var(op_array, ssa, p->ssa_var, 0, p->var, dump_flags);
     763           0 :                         if (p->pi < 0) {
     764           0 :                                 fprintf(stderr, " = Phi(");
     765           0 :                                 for (j = 0; j < cfg->blocks[n].predecessors_count; j++) {
     766           0 :                                         if (j > 0) {
     767           0 :                                                 fprintf(stderr, ", ");
     768             :                                         }
     769           0 :                                         zend_dump_ssa_var(op_array, ssa, p->sources[j], 0, p->var, dump_flags);
     770             :                                 }
     771           0 :                                 fprintf(stderr, ")\n");
     772             :                         } else {
     773           0 :                                 fprintf(stderr, " = Pi<BB%d>(", p->pi);
     774           0 :                                 zend_dump_ssa_var(op_array, ssa, p->sources[0], 0, p->var, dump_flags);
     775           0 :                                 fprintf(stderr, " &");
     776           0 :                                 if (p->has_range_constraint) {
     777           0 :                                         zend_dump_range_constraint(op_array, ssa, &p->constraint.range, dump_flags);
     778             :                                 } else {
     779           0 :                                         zend_dump_type_constraint(op_array, ssa, &p->constraint.type, dump_flags);
     780             :                                 }
     781           0 :                                 fprintf(stderr, ")\n");
     782             :                         }
     783           0 :                         p = p->next;
     784           0 :                 } while (p);
     785             :         }
     786           0 : }
     787             : 
     788           0 : static void zend_dump_op_array_name(const zend_op_array *op_array)
     789             : {
     790           0 :         zend_func_info *func_info = NULL;
     791             : 
     792           0 :         func_info = ZEND_FUNC_INFO(op_array);
     793           0 :         if (op_array->function_name) {
     794           0 :                 if (op_array->scope && op_array->scope->name) {
     795           0 :                         fprintf(stderr, "%s::%s", op_array->scope->name->val, op_array->function_name->val);
     796             :                 } else {
     797           0 :                         fprintf(stderr, "%s", op_array->function_name->val);
     798             :                 }
     799             :         } else {
     800           0 :                 fprintf(stderr, "%s", "$_main");
     801             :         }
     802           0 :         if (func_info && func_info->clone_num > 0) {
     803           0 :                 fprintf(stderr, "_@_clone_%d", func_info->clone_num);
     804             :         }
     805           0 : }
     806             : 
     807           0 : void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, const char *msg, const void *data)
     808             : {
     809             :         int i;
     810           0 :         const zend_cfg *cfg = NULL;
     811           0 :         const zend_ssa *ssa = NULL;
     812           0 :         zend_func_info *func_info = NULL;
     813           0 :         uint32_t func_flags = 0;
     814             : 
     815           0 :         if (dump_flags & (ZEND_DUMP_CFG|ZEND_DUMP_SSA)) {
     816           0 :                 cfg = (const zend_cfg*)data;
     817           0 :                 if (!cfg->blocks) {
     818           0 :                         cfg = data = NULL;
     819             :                 }
     820             :         }
     821           0 :         if (dump_flags & ZEND_DUMP_SSA) {
     822           0 :                 ssa = (const zend_ssa*)data;
     823             :         }
     824             : 
     825           0 :         func_info = ZEND_FUNC_INFO(op_array);
     826           0 :         if (func_info) {
     827           0 :                 func_flags = func_info->flags;
     828             :         }
     829             : 
     830           0 :         fprintf(stderr, "\n");
     831           0 :         zend_dump_op_array_name(op_array);
     832           0 :         fprintf(stderr, ": ; (lines=%d, args=%d",
     833             :                 op_array->last,
     834             :                 op_array->num_args);
     835           0 :         if (func_info && func_info->num_args >= 0) {
     836           0 :                 fprintf(stderr, "/%d", func_info->num_args);
     837             :         }
     838           0 :         fprintf(stderr, ", vars=%d, tmps=%d", op_array->last_var, op_array->T);
     839           0 :         if (ssa) {
     840           0 :                 fprintf(stderr, ", ssa_vars=%d", ssa->vars_count);
     841             :         }
     842           0 :         if (func_flags & ZEND_FUNC_INDIRECT_VAR_ACCESS) {
     843           0 :                 fprintf(stderr, ", dynamic");
     844             :         }
     845           0 :         if (func_flags & ZEND_FUNC_RECURSIVE) {
     846           0 :                 fprintf(stderr, ", recursive");
     847           0 :                 if (func_flags & ZEND_FUNC_RECURSIVE_DIRECTLY) {
     848           0 :                         fprintf(stderr, " directly");
     849             :                 }
     850           0 :                 if (func_flags & ZEND_FUNC_RECURSIVE_INDIRECTLY) {
     851           0 :                         fprintf(stderr, " indirectly");
     852             :                 }
     853             :         }
     854           0 :         if (func_flags & ZEND_FUNC_IRREDUCIBLE) {
     855           0 :                 fprintf(stderr, ", irreducable");
     856             :         }
     857           0 :         if (func_flags & ZEND_FUNC_NO_LOOPS) {
     858           0 :                 fprintf(stderr, ", no_loops");
     859             :         }
     860             : //TODO: this is useful only for JIT???
     861             : #if 0
     862             :         if (info->flags & ZEND_JIT_FUNC_NO_IN_MEM_CVS) {
     863             :                 fprintf(stderr, ", no_in_mem_cvs");
     864             :         }
     865             :         if (info->flags & ZEND_JIT_FUNC_NO_USED_ARGS) {
     866             :                 fprintf(stderr, ", no_used_args");
     867             :         }
     868             :         if (info->flags & ZEND_JIT_FUNC_NO_SYMTAB) {
     869             :                 fprintf(stderr, ", no_symtab");
     870             :         }
     871             :         if (info->flags & ZEND_JIT_FUNC_NO_FRAME) {
     872             :                 fprintf(stderr, ", no_frame");
     873             :         }
     874             :         if (info->flags & ZEND_JIT_FUNC_INLINE) {
     875             :                 fprintf(stderr, ", inline");
     876             :         }
     877             : #endif
     878           0 :         if (func_info && func_info->return_value_used == 0) {
     879           0 :                 fprintf(stderr, ", no_return_value");
     880           0 :         } else if (func_info && func_info->return_value_used == 1) {
     881           0 :                 fprintf(stderr, ", return_value");
     882             :         }
     883           0 :         fprintf(stderr, ")\n");
     884           0 :         if (msg) {
     885           0 :                 fprintf(stderr, "    ; (%s)\n", msg);
     886             :         }
     887           0 :         fprintf(stderr, "    ; %s:%u-%u\n", op_array->filename->val, op_array->line_start, op_array->line_end);
     888             : 
     889           0 :         if (func_info && func_info->num_args > 0) {
     890             :                 uint32_t j;
     891             : 
     892           0 :                 for (j = 0; j < MIN(op_array->num_args, func_info->num_args ); j++) {
     893           0 :                         fprintf(stderr, "    ; arg %d ", j);
     894           0 :                         zend_dump_type_info(func_info->arg_info[j].info.type, func_info->arg_info[j].info.ce, func_info->arg_info[j].info.is_instanceof, dump_flags);
     895           0 :                         zend_dump_range(&func_info->arg_info[j].info.range);
     896           0 :                         fprintf(stderr, "\n");
     897             :                 }
     898             :         }
     899             : 
     900           0 :         if (func_info) {
     901           0 :                 fprintf(stderr, "    ; return ");
     902           0 :                 zend_dump_type_info(func_info->return_info.type, func_info->return_info.ce, func_info->return_info.is_instanceof, dump_flags);
     903           0 :                 zend_dump_range(&func_info->return_info.range);
     904           0 :                 fprintf(stderr, "\n");
     905             :         }
     906             : 
     907           0 :         if (ssa && ssa->var_info) {
     908           0 :                 for (i = 0; i < op_array->last_var; i++) {
     909           0 :                         fprintf(stderr, "    ; ");
     910           0 :                         zend_dump_ssa_var(op_array, ssa, i, IS_CV, i, dump_flags);
     911           0 :                         fprintf(stderr, "\n");
     912             :                 }
     913             :         }
     914             : 
     915           0 :         if (cfg) {
     916             :                 int n;
     917             :                 zend_basic_block *b;
     918             : 
     919           0 :                 for (n = 0; n < cfg->blocks_count; n++) {
     920           0 :                         b = cfg->blocks + n;
     921           0 :                         if (!(dump_flags & ZEND_DUMP_HIDE_UNREACHABLE) || (b->flags & ZEND_BB_REACHABLE)) {
     922             :                                 const zend_op *opline;
     923             :                                 const zend_op *end;
     924             : 
     925           0 :                                 zend_dump_block_header(cfg, op_array, ssa, n, dump_flags);
     926           0 :                                 opline = op_array->opcodes + b->start;
     927           0 :                                 end = opline + b->len;
     928           0 :                                 while (opline < end) {
     929           0 :                                         zend_dump_op(op_array, b, opline, dump_flags, data);
     930           0 :                                         opline++;
     931             :                                 }
     932             :                         }
     933             :                 }
     934           0 :                 if (op_array->last_live_range) {
     935           0 :                         fprintf(stderr, "LIVE RANGES:\n");
     936           0 :                         for (i = 0; i < op_array->last_live_range; i++) {
     937           0 :                                 if (cfg->split_at_live_ranges) {
     938           0 :                                         fprintf(stderr, "        %u: BB%u - BB%u ",
     939           0 :                                                 EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK),
     940           0 :                                                 cfg->map[op_array->live_range[i].start],
     941           0 :                                                 cfg->map[op_array->live_range[i].end]);
     942             :                                 } else {
     943           0 :                                         fprintf(stderr, "        %u: L%u - L%u ",
     944           0 :                                                 EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK),
     945           0 :                                                 op_array->live_range[i].start,
     946           0 :                                                 op_array->live_range[i].end);
     947             :                                 }
     948           0 :                                 switch (op_array->live_range[i].var & ZEND_LIVE_MASK) {
     949             :                                         case ZEND_LIVE_TMPVAR:
     950           0 :                                                 fprintf(stderr, "(tmp/var)\n");
     951           0 :                                                 break;
     952             :                                         case ZEND_LIVE_LOOP:
     953           0 :                                                 fprintf(stderr, "(loop)\n");
     954           0 :                                                 break;
     955             :                                         case ZEND_LIVE_SILENCE:
     956           0 :                                                 fprintf(stderr, "(silence)\n");
     957           0 :                                                 break;
     958             :                                         case ZEND_LIVE_ROPE:
     959           0 :                                                 fprintf(stderr, "(rope)\n");
     960             :                                                 break;
     961             :                                 }
     962             :                         }
     963             :                 }
     964           0 :                 if (op_array->last_try_catch) {
     965           0 :                         fprintf(stderr, "EXCEPTION TABLE:\n");
     966           0 :                         for (i = 0; i < op_array->last_try_catch; i++) {
     967           0 :                                 fprintf(stderr, "        BB%u",
     968           0 :                                         cfg->map[op_array->try_catch_array[i].try_op]);
     969           0 :                                 if (op_array->try_catch_array[i].catch_op) {
     970           0 :                                         fprintf(stderr, ", BB%u",
     971           0 :                                                 cfg->map[op_array->try_catch_array[i].catch_op]);
     972             :                                 } else {
     973           0 :                                         fprintf(stderr, ", -");
     974             :                                 }
     975           0 :                                 if (op_array->try_catch_array[i].finally_op) {
     976           0 :                                         fprintf(stderr, ", BB%u",
     977           0 :                                                 cfg->map[op_array->try_catch_array[i].finally_op]);
     978             :                                 } else {
     979           0 :                                         fprintf(stderr, ", -");
     980             :                                 }
     981           0 :                                 if (op_array->try_catch_array[i].finally_end) {
     982           0 :                                         fprintf(stderr, ", BB%u\n",
     983           0 :                                                 cfg->map[op_array->try_catch_array[i].finally_end]);
     984             :                                 } else {
     985           0 :                                         fprintf(stderr, ", -\n");
     986             :                                 }
     987             :                         }
     988             :                 }
     989             :         } else {
     990           0 :                 const zend_op *opline = op_array->opcodes;
     991           0 :                 const zend_op *end = opline + op_array->last;
     992             : 
     993           0 :                 while (opline < end) {
     994           0 :                         zend_dump_op(op_array, NULL, opline, dump_flags, data);
     995           0 :                         opline++;
     996             :                 }
     997           0 :                 if (op_array->last_live_range) {
     998           0 :                         fprintf(stderr, "LIVE RANGES:\n");
     999           0 :                         for (i = 0; i < op_array->last_live_range; i++) {
    1000           0 :                                 fprintf(stderr, "        %u: L%u - L%u ",
    1001           0 :                                         EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK),
    1002           0 :                                         op_array->live_range[i].start,
    1003           0 :                                         op_array->live_range[i].end);
    1004           0 :                                 switch (op_array->live_range[i].var & ZEND_LIVE_MASK) {
    1005             :                                         case ZEND_LIVE_TMPVAR:
    1006           0 :                                                 fprintf(stderr, "(tmp/var)\n");
    1007           0 :                                                 break;
    1008             :                                         case ZEND_LIVE_LOOP:
    1009           0 :                                                 fprintf(stderr, "(loop)\n");
    1010           0 :                                                 break;
    1011             :                                         case ZEND_LIVE_SILENCE:
    1012           0 :                                                 fprintf(stderr, "(silence)\n");
    1013           0 :                                                 break;
    1014             :                                         case ZEND_LIVE_ROPE:
    1015           0 :                                                 fprintf(stderr, "(rope)\n");
    1016             :                                                 break;
    1017             :                                 }
    1018             :                         }
    1019             :                 }
    1020           0 :                 if (op_array->last_try_catch) {
    1021           0 :                         fprintf(stderr, "EXCEPTION TABLE:\n");
    1022           0 :                         for (i = 0; i < op_array->last_try_catch; i++) {
    1023           0 :                                 fprintf(stderr, "        L%u",
    1024           0 :                                         op_array->try_catch_array[i].try_op);
    1025           0 :                                 if (op_array->try_catch_array[i].catch_op) {
    1026           0 :                                         fprintf(stderr, ", L%u",
    1027           0 :                                                 op_array->try_catch_array[i].catch_op);
    1028             :                                 } else {
    1029           0 :                                         fprintf(stderr, ", -");
    1030             :                                 }
    1031           0 :                                 if (op_array->try_catch_array[i].finally_op) {
    1032           0 :                                         fprintf(stderr, ", L%u",
    1033           0 :                                                 op_array->try_catch_array[i].finally_op);
    1034             :                                 } else {
    1035           0 :                                         fprintf(stderr, ", -");
    1036             :                                 }
    1037           0 :                                 if (op_array->try_catch_array[i].finally_end) {
    1038           0 :                                         fprintf(stderr, ", L%u\n",
    1039           0 :                                                 op_array->try_catch_array[i].finally_end);
    1040             :                                 } else {
    1041           0 :                                         fprintf(stderr, ", -\n");
    1042             :                                 }
    1043             :                         }
    1044             :                 }
    1045             :         }
    1046           0 : }
    1047             : 
    1048           0 : void zend_dump_dominators(const zend_op_array *op_array, const zend_cfg *cfg)
    1049             : {
    1050             :         int j;
    1051             : 
    1052           0 :         fprintf(stderr, "\nDOMINATORS-TREE for \"");
    1053           0 :         zend_dump_op_array_name(op_array);
    1054           0 :         fprintf(stderr, "\"\n");
    1055           0 :         for (j = 0; j < cfg->blocks_count; j++) {
    1056           0 :                 zend_basic_block *b = cfg->blocks + j;
    1057           0 :                 if (b->flags & ZEND_BB_REACHABLE) {
    1058           0 :                         zend_dump_block_info(cfg, j, 0);
    1059             :                 }
    1060             :         }
    1061           0 : }
    1062             : 
    1063           0 : void zend_dump_variables(const zend_op_array *op_array)
    1064             : {
    1065             :         int j;
    1066             : 
    1067           0 :         fprintf(stderr, "\nCV Variables for \"");
    1068           0 :         zend_dump_op_array_name(op_array);
    1069           0 :         fprintf(stderr, "\"\n");
    1070           0 :         for (j = 0; j < op_array->last_var; j++) {
    1071           0 :                 fprintf(stderr, "    ");
    1072           0 :                 zend_dump_var(op_array, IS_CV, j);
    1073           0 :                 fprintf(stderr, "\n");
    1074             :         }
    1075           0 : }
    1076             : 
    1077           0 : void zend_dump_ssa_variables(const zend_op_array *op_array, const zend_ssa *ssa, uint32_t dump_flags)
    1078             : {
    1079             :         int j;
    1080             : 
    1081           0 :         if (ssa->vars) {
    1082           0 :                 fprintf(stderr, "\nSSA Variable for \"");
    1083           0 :                 zend_dump_op_array_name(op_array);
    1084           0 :                 fprintf(stderr, "\"\n");
    1085             : 
    1086           0 :                 for (j = 0; j < ssa->vars_count; j++) {
    1087           0 :                         fprintf(stderr, "    ");
    1088           0 :                         zend_dump_ssa_var(op_array, ssa, j, IS_CV, ssa->vars[j].var, dump_flags);
    1089           0 :                         if (ssa->vars[j].scc >= 0) {
    1090           0 :                                 if (ssa->vars[j].scc_entry) {
    1091           0 :                                         fprintf(stderr, " *");
    1092             :                                 }  else {
    1093           0 :                                         fprintf(stderr, "  ");
    1094             :                                 }
    1095           0 :                                 fprintf(stderr, "SCC=%d", ssa->vars[j].scc);
    1096             :                         }
    1097           0 :                         fprintf(stderr, "\n");
    1098             :                 }
    1099             :         }
    1100           0 : }
    1101             : 
    1102           0 : static void zend_dump_var_set(const zend_op_array *op_array, const char *name, zend_bitset set)
    1103             : {
    1104           0 :         int first = 1;
    1105             :         uint32_t i;
    1106             : 
    1107           0 :         fprintf(stderr, "    ; %s = {", name);
    1108           0 :         for (i = 0; i < op_array->last_var + op_array->T; i++) {
    1109           0 :                 if (zend_bitset_in(set, i)) {
    1110           0 :                         if (first) {
    1111           0 :                                 first = 0;
    1112             :                         } else {
    1113           0 :                                 fprintf(stderr, ", ");
    1114             :                         }
    1115           0 :                         zend_dump_var(op_array, IS_CV, i);
    1116             :                 }
    1117             :         }
    1118           0 :         fprintf(stderr, "}\n");
    1119           0 : }
    1120             : 
    1121           0 : void zend_dump_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zend_dfg *dfg)
    1122             : {
    1123             :         int j;
    1124           0 :         fprintf(stderr, "\nVariable Liveness for \"");
    1125           0 :         zend_dump_op_array_name(op_array);
    1126           0 :         fprintf(stderr, "\"\n");
    1127             : 
    1128           0 :         for (j = 0; j < cfg->blocks_count; j++) {
    1129           0 :                 fprintf(stderr, "  BB%d:\n", j);
    1130           0 :                 zend_dump_var_set(op_array, "def", DFG_BITSET(dfg->def, dfg->size, j));
    1131           0 :                 zend_dump_var_set(op_array, "use", DFG_BITSET(dfg->use, dfg->size, j));
    1132           0 :                 zend_dump_var_set(op_array, "in ", DFG_BITSET(dfg->in,  dfg->size, j));
    1133           0 :                 zend_dump_var_set(op_array, "out", DFG_BITSET(dfg->out, dfg->size, j));
    1134             :         }
    1135           0 : }
    1136             : 
    1137           0 : void zend_dump_phi_placement(const zend_op_array *op_array, const zend_ssa *ssa)
    1138             : {
    1139             :         int j;
    1140           0 :         zend_ssa_block *ssa_blocks = ssa->blocks;
    1141           0 :         int blocks_count = ssa->cfg.blocks_count;
    1142             : 
    1143           0 :         fprintf(stderr, "\nSSA Phi() Placement for \"");
    1144           0 :         zend_dump_op_array_name(op_array);
    1145           0 :         fprintf(stderr, "\"\n");
    1146           0 :         for (j = 0; j < blocks_count; j++) {
    1147           0 :                 if (ssa_blocks && ssa_blocks[j].phis) {
    1148           0 :                         zend_ssa_phi *p = ssa_blocks[j].phis;
    1149           0 :                         int first = 1;
    1150             : 
    1151           0 :                         fprintf(stderr, "  BB%d:\n", j);
    1152           0 :                         if (p->pi >= 0) {
    1153           0 :                                 fprintf(stderr, "    ; pi={");
    1154             :                         } else {
    1155           0 :                                 fprintf(stderr, "    ; phi={");
    1156             :                         }
    1157             :                         do {
    1158           0 :                                 if (first) {
    1159           0 :                                         first = 0;
    1160             :                                 } else {
    1161           0 :                                         fprintf(stderr, ", ");
    1162             :                                 }
    1163           0 :                                 zend_dump_var(op_array, IS_CV, p->var);
    1164           0 :                                 p = p->next;
    1165           0 :                         } while (p);
    1166           0 :                         fprintf(stderr, "}\n");
    1167             :                 }
    1168             :         }
    1169           0 : }
    1170             : 
    1171             : /*
    1172             :  * Local variables:
    1173             :  * tab-width: 4
    1174             :  * c-basic-offset: 4
    1175             :  * indent-tabs-mode: t
    1176             :  * End:
    1177             :  */

Generated by: LCOV version 1.10

Generated at Sun, 15 Oct 2017 12:26:23 +0000 (8 days ago)

Copyright © 2005-2017 The PHP Group
All rights reserved.