zend_cfg.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine, CFG - Control Flow Graph |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 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. | https://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@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. #ifndef ZEND_CFG_H
  19. #define ZEND_CFG_H
  20. /* zend_basic_block.flags */
  21. #define ZEND_BB_START (1<<0) /* first block */
  22. #define ZEND_BB_FOLLOW (1<<1) /* follows the next block */
  23. #define ZEND_BB_TARGET (1<<2) /* jump target */
  24. #define ZEND_BB_EXIT (1<<3) /* without successors */
  25. #define ZEND_BB_ENTRY (1<<4) /* stackless entry */
  26. #define ZEND_BB_TRY (1<<5) /* start of try block */
  27. #define ZEND_BB_CATCH (1<<6) /* start of catch block */
  28. #define ZEND_BB_FINALLY (1<<7) /* start of finally block */
  29. #define ZEND_BB_FINALLY_END (1<<8) /* end of finally block */
  30. #define ZEND_BB_UNREACHABLE_FREE (1<<11) /* unreachable loop free */
  31. #define ZEND_BB_RECV_ENTRY (1<<12) /* RECV entry */
  32. #define ZEND_BB_LOOP_HEADER (1<<16)
  33. #define ZEND_BB_IRREDUCIBLE_LOOP (1<<17)
  34. #define ZEND_BB_REACHABLE (1U<<31)
  35. #define ZEND_BB_PROTECTED (ZEND_BB_ENTRY|ZEND_BB_RECV_ENTRY|ZEND_BB_TRY|ZEND_BB_CATCH|ZEND_BB_FINALLY|ZEND_BB_FINALLY_END|ZEND_BB_UNREACHABLE_FREE)
  36. typedef struct _zend_basic_block {
  37. int *successors; /* successor block indices */
  38. uint32_t flags;
  39. uint32_t start; /* first opcode number */
  40. uint32_t len; /* number of opcodes */
  41. int successors_count; /* number of successors */
  42. int predecessors_count; /* number of predecessors */
  43. int predecessor_offset; /* offset of 1-st predecessor */
  44. int idom; /* immediate dominator block */
  45. int loop_header; /* closest loop header, or -1 */
  46. int level; /* steps away from the entry in the dom. tree */
  47. int children; /* list of dominated blocks */
  48. int next_child; /* next dominated block */
  49. int successors_storage[2]; /* up to 2 successor blocks */
  50. } zend_basic_block;
  51. /*
  52. +------------+---+---+---+---+---+
  53. | |OP1|OP2|EXT| 0 | 1 |
  54. +------------+---+---+---+---+---+
  55. |JMP |ADR| | |OP1| - |
  56. |JMPZ | |ADR| |OP2|FOL|
  57. |JMPNZ | |ADR| |OP2|FOL|
  58. |JMPZNZ | |ADR|ADR|OP2|EXT|
  59. |JMPZ_EX | |ADR| |OP2|FOL|
  60. |JMPNZ_EX | |ADR| |OP2|FOL|
  61. |JMP_SET | |ADR| |OP2|FOL|
  62. |COALESCE | |ADR| |OP2|FOL|
  63. |ASSERT_CHK | |ADR| |OP2|FOL|
  64. |NEW | |ADR| |OP2|FOL|
  65. |DCL_ANON* |ADR| | |OP1|FOL|
  66. |FE_RESET_* | |ADR| |OP2|FOL|
  67. |FE_FETCH_* | | |ADR|EXT|FOL|
  68. |CATCH | | |ADR|EXT|FOL|
  69. |FAST_CALL |ADR| | |OP1|FOL|
  70. |FAST_RET | | | | - | - |
  71. |RETURN* | | | | - | - |
  72. |EXIT | | | | - | - |
  73. |THROW | | | | - | - |
  74. |* | | | |FOL| - |
  75. +------------+---+---+---+---+---+
  76. */
  77. typedef struct _zend_cfg {
  78. int blocks_count; /* number of basic blocks */
  79. int edges_count; /* number of edges */
  80. zend_basic_block *blocks; /* array of basic blocks */
  81. int *predecessors;
  82. uint32_t *map;
  83. uint32_t flags;
  84. } zend_cfg;
  85. /* Build Flags */
  86. #define ZEND_CFG_STACKLESS (1<<30)
  87. #define ZEND_SSA_DEBUG_LIVENESS (1<<29)
  88. #define ZEND_SSA_DEBUG_PHI_PLACEMENT (1<<28)
  89. #define ZEND_SSA_RC_INFERENCE (1<<27)
  90. #define ZEND_CFG_NO_ENTRY_PREDECESSORS (1<<25)
  91. #define ZEND_CFG_RECV_ENTRY (1<<24)
  92. #define ZEND_CALL_TREE (1<<23)
  93. #define ZEND_SSA_USE_CV_RESULTS (1<<22)
  94. #define CRT_CONSTANT_EX(op_array, opline, node) \
  95. (((op_array)->fn_flags & ZEND_ACC_DONE_PASS_TWO) ? \
  96. RT_CONSTANT(opline, (node)) \
  97. : \
  98. CT_CONSTANT_EX(op_array, (node).constant) \
  99. )
  100. #define CRT_CONSTANT(node) \
  101. CRT_CONSTANT_EX(op_array, opline, node)
  102. #define RETURN_VALUE_USED(opline) \
  103. ((opline)->result_type != IS_UNUSED)
  104. BEGIN_EXTERN_C()
  105. ZEND_API int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_cfg *cfg);
  106. void zend_cfg_remark_reachable_blocks(const zend_op_array *op_array, zend_cfg *cfg);
  107. ZEND_API int zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg);
  108. ZEND_API int zend_cfg_compute_dominators_tree(const zend_op_array *op_array, zend_cfg *cfg);
  109. ZEND_API int zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg);
  110. END_EXTERN_C()
  111. #endif /* ZEND_CFG_H */