Commit e2aee31ec97 for php.net
commit e2aee31ec973afc51096e98b80c0201d47133459
Author: Gina Peter Banyard <girgias@php.net>
Date: Wed Aug 19 02:38:03 2026 +0100
Optimizer: add const qualifiers (#22009)
diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c
index 3775f8165c3..6f67fb0e0a7 100644
--- a/Zend/Optimizer/block_pass.c
+++ b/Zend/Optimizer/block_pass.c
@@ -1702,7 +1702,7 @@ static void zend_merge_blocks(const zend_op_array *op_array, const zend_cfg *cfg
void zend_optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx)
{
zend_cfg cfg;
- zend_basic_block *blocks, *end, *b;
+ zend_basic_block *blocks, *b;
int pass;
uint32_t bitset_len;
zend_bitset usage;
@@ -1730,7 +1730,7 @@ void zend_optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx)
jmp_hitlist = zend_arena_alloc(&ctx->arena, cfg.blocks_count * sizeof(int));
blocks = cfg.blocks;
- end = blocks + cfg.blocks_count;
+ const zend_basic_block *end = blocks + cfg.blocks_count;
for (pass = 0; pass < PASSES; pass++) {
opt_count = 0;
diff --git a/Zend/Optimizer/compact_literals.c b/Zend/Optimizer/compact_literals.c
index 8277092d76b..a73b46c0e33 100644
--- a/Zend/Optimizer/compact_literals.c
+++ b/Zend/Optimizer/compact_literals.c
@@ -42,26 +42,27 @@ typedef struct _literal_info {
info[n].num_related = (related); \
} while (0)
-static uint32_t add_static_slot(HashTable *hash,
- zend_op_array *op_array,
- uint32_t op1,
- uint32_t op2,
- uint32_t kind,
- uint32_t *cache_size)
-{
+static uint32_t add_static_slot(
+ HashTable *hash,
+ const zend_op_array *op_array,
+ uint32_t op1,
+ uint32_t op2,
+ uint32_t kind,
+ uint32_t *cache_size
+) {
uint32_t ret;
- zval *class_name = &op_array->literals[op1];
- zval *prop_name = &op_array->literals[op2];
- zval *pos, tmp;
+ const zval *class_name = &op_array->literals[op1];
+ const zval *prop_name = &op_array->literals[op2];
zend_string *key = zend_create_member_string(Z_STR_P(class_name), Z_STR_P(prop_name));
ZSTR_H(key) = zend_string_hash_func(key);
ZSTR_H(key) += kind;
- pos = zend_hash_find(hash, key);
+ const zval *pos = zend_hash_find(hash, key);
if (pos) {
ret = Z_LVAL_P(pos);
} else {
+ zval tmp;
ret = *cache_size;
*cache_size += (kind == LITERAL_STATIC_PROPERTY ? 3 : 2) * sizeof(void *);
ZVAL_LONG(&tmp, ret);
@@ -78,7 +79,7 @@ static inline void bias_key(zend_string *key, uint32_t bias)
ZSTR_H(key) = zend_string_hash_val(key) + bias;
}
-static zend_string *create_str_cache_key(zval *literal, uint8_t num_related)
+static zend_string *create_str_cache_key(const zval *literal, uint8_t num_related)
{
ZEND_ASSERT(Z_TYPE_P(literal) == IS_STRING);
if (num_related == 1) {
diff --git a/Zend/Optimizer/compact_vars.c b/Zend/Optimizer/compact_vars.c
index b4a861d3595..f6c39e9fe16 100644
--- a/Zend/Optimizer/compact_vars.c
+++ b/Zend/Optimizer/compact_vars.c
@@ -33,7 +33,7 @@ void zend_optimizer_compact_vars(zend_op_array *op_array) {
/* Determine which CVs are used */
zend_bitset_clear(used_vars, used_vars_len);
for (i = 0; i < op_array->last; i++) {
- zend_op *opline = &op_array->opcodes[i];
+ const zend_op *opline = &op_array->opcodes[i];
if (opline->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
zend_bitset_incl(used_vars, VAR_NUM(opline->op1.var));
}
diff --git a/Zend/Optimizer/dfa_pass.c b/Zend/Optimizer/dfa_pass.c
index 8826ca41641..ff4c2de4eaf 100644
--- a/Zend/Optimizer/dfa_pass.c
+++ b/Zend/Optimizer/dfa_pass.c
@@ -108,7 +108,7 @@ zend_result zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ct
return SUCCESS;
}
-static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa, zend_optimizer_ctx *ctx)
+static void zend_ssa_remove_nops(zend_op_array *op_array, const zend_ssa *ssa, zend_optimizer_ctx *ctx)
{
zend_basic_block *blocks = ssa->cfg.blocks;
zend_basic_block *blocks_end = blocks + ssa->cfg.blocks_count;
@@ -290,9 +290,9 @@ static inline bool can_elide_list_type(
}
static inline bool can_elide_return_type_check(
- const zend_script *script, zend_op_array *op_array, zend_ssa *ssa, zend_ssa_op *ssa_op) {
- zend_arg_info *arg_info = &op_array->arg_info[-1];
- zend_ssa_var_info *use_info = &ssa->var_info[ssa_op->op1_use];
+ const zend_script *script, const zend_op_array *op_array, const zend_ssa *ssa, const zend_ssa_op *ssa_op) {
+ const zend_arg_info *arg_info = &op_array->arg_info[-1];
+ const zend_ssa_var_info *use_info = &ssa->var_info[ssa_op->op1_use];
uint32_t use_type = use_info->type & (MAY_BE_ANY|MAY_BE_UNDEF);
if (use_type & MAY_BE_REF) {
return false;
@@ -317,7 +317,7 @@ static inline bool can_elide_return_type_check(
}
static bool opline_supports_assign_contraction(
- zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, int src_var, uint32_t cv_var) {
+ const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, int src_var, uint32_t cv_var) {
if (opline->opcode == ZEND_NEW) {
/* see Zend/tests/generators/aborted_yield_during_new.phpt */
return false;
@@ -378,7 +378,7 @@ static bool opline_supports_assign_contraction(
return true;
}
-static bool variable_defined_or_used_in_range(zend_ssa *ssa, int var, int start, int end)
+static bool variable_defined_or_used_in_range(const zend_ssa *ssa, int var, int start, int end)
{
while (start < end) {
const zend_ssa_op *ssa_op = &ssa->ops[start];
@@ -599,11 +599,11 @@ static void replace_predecessor(zend_ssa *ssa, int block_id, int old_pred, int n
}
}
-static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa, int from, int to, int new_to)
+static void zend_ssa_replace_control_link(const zend_op_array *op_array, zend_ssa *ssa, int from, int to, int new_to)
{
- zend_basic_block *src = &ssa->cfg.blocks[from];
- zend_basic_block *old = &ssa->cfg.blocks[to];
- zend_basic_block *dst = &ssa->cfg.blocks[new_to];
+ const zend_basic_block *src = &ssa->cfg.blocks[from];
+ const zend_basic_block *old = &ssa->cfg.blocks[to];
+ const zend_basic_block *dst = &ssa->cfg.blocks[new_to];
zend_op *opline;
for (uint32_t i = 0; i < src->successors_count; i++) {
@@ -671,7 +671,7 @@ static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa
replace_predecessor(ssa, new_to, to, from);
}
-static void zend_ssa_unlink_block(zend_op_array *op_array, zend_ssa *ssa, zend_basic_block *block, uint32_t block_num)
+static void zend_ssa_unlink_block(const zend_op_array *op_array, zend_ssa *ssa, const zend_basic_block *block, uint32_t block_num)
{
if (block->predecessors_count == 1 && ssa->blocks[block_num].phis == NULL) {
int *predecessors;
@@ -865,7 +865,7 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa)
break;
case ZEND_COALESCE:
{
- zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
+ const zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
if (opline->op1_type == IS_CONST
&& var->use_chain < 0 && var->phi_use_chain == NULL) {
if (Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op1.constant)) == IS_NULL) {
@@ -887,7 +887,7 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa)
}
case ZEND_JMP_NULL:
{
- zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
+ const zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
if (opline->op1_type == IS_CONST
&& var->use_chain < 0 && var->phi_use_chain == NULL) {
if (Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op1.constant)) == IS_NULL) {
@@ -932,8 +932,8 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa)
uint32_t target;
if (correct_type) {
- HashTable *jmptable = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, opline->op2.constant));
- zval *jmp_zv = type == IS_LONG
+ const HashTable *jmptable = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, opline->op2.constant));
+ const zval *jmp_zv = type == IS_LONG
? zend_hash_index_find(jmptable, Z_LVAL_P(zv))
: zend_hash_find(jmptable, Z_STR_P(zv));
@@ -985,7 +985,7 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa)
return removed_ops;
}
-static bool zend_dfa_try_to_replace_result(zend_op_array *op_array, zend_ssa *ssa, int def, int cv_var)
+static bool zend_dfa_try_to_replace_result(const zend_op_array *op_array, const zend_ssa *ssa, int def, int cv_var)
{
int result_var = ssa->ops[def].result_def;
uint32_t cv = EX_NUM_TO_VAR(ssa->vars[cv_var].var);
diff --git a/Zend/Optimizer/escape_analysis.c b/Zend/Optimizer/escape_analysis.c
index 8dbd6855d68..02f986d6e8f 100644
--- a/Zend/Optimizer/escape_analysis.c
+++ b/Zend/Optimizer/escape_analysis.c
@@ -71,11 +71,10 @@ static zend_always_inline void union_find_unite(int *parent, int *size, int i, i
}
/* }}} */
-static zend_result zend_build_equi_escape_sets(int *parent, zend_op_array *op_array, zend_ssa *ssa) /* {{{ */
+static zend_result zend_build_equi_escape_sets(int *parent, const zend_op_array *op_array, const zend_ssa *ssa) /* {{{ */
{
zend_ssa_var *ssa_vars = ssa->vars;
int ssa_vars_count = ssa->vars_count;
- zend_ssa_phi *p;
int i;
int *size;
ALLOCA_FLAG(use_heap)
@@ -88,7 +87,7 @@ static zend_result zend_build_equi_escape_sets(int *parent, zend_op_array *op_ar
for (i = 0; i < ssa_vars_count; i++) {
if (ssa_vars[i].definition_phi) {
- p = ssa_vars[i].definition_phi;
+ const zend_ssa_phi *p = ssa_vars[i].definition_phi;
if (p->pi >= 0) {
union_find_unite(parent, size, i, p->sources[0]);
} else {
@@ -98,8 +97,8 @@ static zend_result zend_build_equi_escape_sets(int *parent, zend_op_array *op_ar
}
} else if (ssa_vars[i].definition >= 0) {
int def = ssa_vars[i].definition;
- zend_ssa_op *op = ssa->ops + def;
- zend_op *opline = op_array->opcodes + def;
+ const zend_ssa_op *op = ssa->ops + def;
+ const zend_op *opline = op_array->opcodes + def;
if (op->op1_def >= 0) {
if (op->op1_use >= 0) {
@@ -145,9 +144,9 @@ static zend_result zend_build_equi_escape_sets(int *parent, zend_op_array *op_ar
}
/* }}} */
-static bool is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, int var, const zend_script *script) /* {{{ */
+static bool is_allocation_def(const zend_op_array *op_array, const zend_ssa *ssa, int def, int var, const zend_script *script) /* {{{ */
{
- zend_ssa_op *ssa_op = ssa->ops + def;
+ const zend_ssa_op *ssa_op = ssa->ops + def;
zend_op *opline = op_array->opcodes + def;
if (ssa_op->result_def == var) {
@@ -156,7 +155,7 @@ static bool is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, i
return true;
case ZEND_NEW: {
/* objects with destructors should escape */
- zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1(
+ const zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1(
script, op_array, opline);
uint32_t forbidden_flags =
/* These flags will always cause an exception */
@@ -216,10 +215,10 @@ static bool is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, i
}
/* }}} */
-static bool is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int var, const zend_script *script) /* {{{ */
+static bool is_local_def(const zend_op_array *op_array, const zend_ssa *ssa, int def, int var, const zend_script *script) /* {{{ */
{
- zend_ssa_op *op = ssa->ops + def;
- zend_op *opline = op_array->opcodes + def;
+ const zend_ssa_op *op = ssa->ops + def;
+ const zend_op *opline = op_array->opcodes + def;
if (op->result_def == var) {
switch (opline->opcode) {
@@ -230,7 +229,7 @@ static bool is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int va
return true;
case ZEND_NEW: {
/* objects with destructors should escape */
- zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1(
+ const zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1(
script, op_array, opline);
if (ce
&& !ce->create_object
@@ -266,10 +265,10 @@ static bool is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int va
}
/* }}} */
-static bool is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int var) /* {{{ */
+static bool is_escape_use(const zend_op_array *op_array, const zend_ssa *ssa, int use, int var) /* {{{ */
{
- zend_ssa_op *ssa_op = ssa->ops + use;
- zend_op *opline = op_array->opcodes + use;
+ const zend_ssa_op *ssa_op = ssa->ops + use;
+ const zend_op *opline = op_array->opcodes + use;
if (ssa_op->op1_use == var) {
switch (opline->opcode) {
@@ -377,7 +376,7 @@ static bool is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int v
}
/* }}} */
-zend_result zend_ssa_escape_analysis(const zend_script *script, zend_op_array *op_array, zend_ssa *ssa) /* {{{ */
+zend_result zend_ssa_escape_analysis(const zend_script *script, const zend_op_array *op_array, const zend_ssa *ssa) /* {{{ */
{
zend_ssa_var *ssa_vars = ssa->vars;
int ssa_vars_count = ssa->vars_count;
@@ -474,8 +473,8 @@ zend_result zend_ssa_escape_analysis(const zend_script *script, zend_op_array *o
root = ees[i];
if (ssa_vars[root].escape_state == ESCAPE_STATE_NO_ESCAPE) {
FOREACH_USE(ssa_vars + i, use) {
- zend_ssa_op *op = ssa->ops + use;
- zend_op *opline = op_array->opcodes + use;
+ const zend_ssa_op *op = ssa->ops + use;
+ const zend_op *opline = op_array->opcodes + use;
int enclosing_root;
if (opline->opcode == ZEND_OP_DATA &&
diff --git a/Zend/Optimizer/optimize_temp_vars_5.c b/Zend/Optimizer/optimize_temp_vars_5.c
index 6a5c99f4755..057944130e8 100644
--- a/Zend/Optimizer/optimize_temp_vars_5.c
+++ b/Zend/Optimizer/optimize_temp_vars_5.c
@@ -108,7 +108,7 @@ void zend_optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_c
opline->opcode == ZEND_RETURN_BY_REF ||
opline->opcode == ZEND_FREE ||
opline->opcode == ZEND_FE_FREE)) {
- zend_op *curr = opline;
+ const zend_op *curr = opline;
while (--curr >= end) {
if (curr->opcode == ZEND_FAST_CALL) {
diff --git a/Zend/Optimizer/pass3.c b/Zend/Optimizer/pass3.c
index 2d2a4468522..8aa6ea38f20 100644
--- a/Zend/Optimizer/pass3.c
+++ b/Zend/Optimizer/pass3.c
@@ -29,7 +29,7 @@
#include "zend_vm.h"
/* we use "jmp_hitlist" to avoid infinity loops during jmp optimization */
-static zend_always_inline bool in_hitlist(zend_op *target, zend_op **jmp_hitlist, int jmp_hitlist_count)
+static zend_always_inline bool in_hitlist(const zend_op *target, zend_op **jmp_hitlist, int jmp_hitlist_count)
{
int i;
@@ -51,7 +51,6 @@ static zend_always_inline bool in_hitlist(zend_op *target, zend_op **jmp_hitlist
void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx)
{
zend_op *opline;
- zend_op *end;
zend_op *target;
zend_op **jmp_hitlist;
int jmp_hitlist_count;
@@ -59,7 +58,7 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx)
jmp_hitlist = (zend_op**)do_alloca(sizeof(zend_op*)*op_array->last, use_heap);
opline = op_array->opcodes;
- end = opline + op_array->last;
+ const zend_op *end = opline + op_array->last;
while (opline < end) {
diff --git a/Zend/Optimizer/sccp.c b/Zend/Optimizer/sccp.c
index ba94e9b7b91..72ba6d98888 100644
--- a/Zend/Optimizer/sccp.c
+++ b/Zend/Optimizer/sccp.c
@@ -96,7 +96,7 @@ typedef struct _sccp_ctx {
#define MAKE_TOP(zv) (Z_TYPE_INFO_P(zv) = TOP)
#define MAKE_BOT(zv) (Z_TYPE_INFO_P(zv) = BOT)
-static void scp_dump_value(zval *zv) {
+static void scp_dump_value(const zval *zv) {
if (IS_TOP(zv)) {
fprintf(stderr, " top");
} else if (IS_BOT(zv)) {
@@ -138,13 +138,13 @@ static void dup_partial_object(zval *dst, const zval *src)
Z_ARR_P(dst) = zend_array_dup(Z_ARR_P(src));
}
-static inline bool value_known(zval *zv) {
+static inline bool value_known(const zval *zv) {
return !IS_TOP(zv) && !IS_BOT(zv);
}
/* Sets new value for variable and ensures that it is lower or equal
* the previous one in the constant propagation lattice. */
-static void set_value(scdf_ctx *scdf, sccp_ctx *ctx, int var, const zval *new) {
+static void set_value(const scdf_ctx *scdf, const sccp_ctx *ctx, int var, const zval *new) {
zval *value = &ctx->values[var];
if (IS_BOT(value) || IS_TOP(new)) {
return;
@@ -184,7 +184,7 @@ static void set_value(scdf_ctx *scdf, sccp_ctx *ctx, int var, const zval *new) {
#endif
}
-static zval *get_op1_value(sccp_ctx *ctx, zend_op *opline, const zend_ssa_op *ssa_op) {
+static zval *get_op1_value(const sccp_ctx *ctx, const zend_op *opline, const zend_ssa_op *ssa_op) {
if (opline->op1_type == IS_CONST) {
return CT_CONSTANT_EX(ctx->scdf.op_array, opline->op1.constant);
} else if (ssa_op->op1_use != -1) {
@@ -194,7 +194,7 @@ static zval *get_op1_value(sccp_ctx *ctx, zend_op *opline, const zend_ssa_op *ss
}
}
-static zval *get_op2_value(sccp_ctx *ctx, const zend_op *opline, const zend_ssa_op *ssa_op) {
+static zval *get_op2_value(const sccp_ctx *ctx, const zend_op *opline, const zend_ssa_op *ssa_op) {
if (opline->op2_type == IS_CONST) {
return CT_CONSTANT_EX(ctx->scdf.op_array, opline->op2.constant);
} else if (ssa_op->op2_use != -1) {
@@ -275,7 +275,7 @@ static bool can_replace_op1(
}
static bool can_replace_op2(
- const zend_op_array *op_array, zend_op *opline, zend_ssa_op *ssa_op) {
+ const zend_op_array *op_array, const zend_op *opline, zend_ssa_op *ssa_op) {
switch (opline->opcode) {
/* Do not accept CONST */
case ZEND_DECLARE_CLASS_DELAYED:
@@ -288,7 +288,7 @@ static bool can_replace_op2(
}
static bool try_replace_op1(
- sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op, int var, zval *value) {
+ const sccp_ctx *ctx, zend_op *opline, const zend_ssa_op *ssa_op, int var, zval *value) {
if (ssa_op->op1_use == var && can_replace_op1(ctx->scdf.op_array, opline, ssa_op)) {
zval zv;
ZVAL_COPY(&zv, value);
@@ -301,7 +301,7 @@ static bool try_replace_op1(
}
static bool try_replace_op2(
- sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op, int var, zval *value) {
+ const sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op, int var, zval *value) {
if (ssa_op->op2_use == var && can_replace_op2(ctx->scdf.op_array, opline, ssa_op)) {
zval zv;
ZVAL_COPY(&zv, value);
@@ -322,7 +322,7 @@ static inline zend_result ct_eval_binary_op(zval *result, uint8_t binop, zval *o
return zend_optimizer_eval_binary_op(result, binop, op1, op2);
}
-static inline zend_result ct_eval_bool_cast(zval *result, zval *op) {
+static inline zend_result ct_eval_bool_cast(zval *result, const zval *op) {
if (IS_PARTIAL_ARRAY(op)) {
if (zend_hash_num_elements(Z_ARRVAL_P(op)) == 0) {
/* An empty partial array may be non-empty at runtime, we don't know whether the
@@ -342,7 +342,7 @@ static inline zend_result ct_eval_bool_cast(zval *result, zval *op) {
return SUCCESS;
}
-static inline zend_result zval_to_string_offset(zend_long *result, zval *op) {
+static inline zend_result zval_to_string_offset(zend_long *result, const zval *op) {
switch (Z_TYPE_P(op)) {
case IS_LONG:
*result = Z_LVAL_P(op);
@@ -358,7 +358,7 @@ static inline zend_result zval_to_string_offset(zend_long *result, zval *op) {
}
}
-static inline zend_result fetch_array_elem(zval **result, zval *op1, zval *op2) {
+static inline zend_result fetch_array_elem(zval **result, const zval *op1, const zval *op2) {
switch (Z_TYPE_P(op2)) {
case IS_NULL:
return FAILURE;
@@ -387,7 +387,7 @@ static inline zend_result fetch_array_elem(zval **result, zval *op1, zval *op2)
}
}
-static inline zend_result ct_eval_fetch_dim(zval *result, zval *op1, zval *op2, int support_strings) {
+static inline zend_result ct_eval_fetch_dim(zval *result, const zval *op1, const zval *op2, int support_strings) {
if (Z_TYPE_P(op1) == IS_ARRAY || IS_PARTIAL_ARRAY(op1)) {
zval *value;
if (fetch_array_elem(&value, op1, op2) == SUCCESS && value && !IS_BOT(value)) {
@@ -424,7 +424,7 @@ static inline zend_result ct_eval_isset_isempty(zval *result, uint32_t extended_
}
}
-static inline zend_result ct_eval_isset_dim(zval *result, uint32_t extended_value, zval *op1, zval *op2) {
+static inline zend_result ct_eval_isset_dim(zval *result, uint32_t extended_value, const zval *op1, const zval *op2) {
if (Z_TYPE_P(op1) == IS_ARRAY || IS_PARTIAL_ARRAY(op1)) {
zval *value;
if (fetch_array_elem(&value, op1, op2) == FAILURE) {
@@ -526,7 +526,7 @@ static inline zend_result ct_eval_add_array_elem(zval *result, zval *value, cons
return SUCCESS;
}
-static inline zend_result ct_eval_add_array_unpack(zval *result, zval *array) {
+static inline zend_result ct_eval_add_array_unpack(zval *result, const zval *array) {
zend_string *key;
zval *value;
if (Z_TYPE_P(array) != IS_ARRAY) {
@@ -587,7 +587,7 @@ static inline zend_result ct_eval_assign_dim(zval *result, zval *value, const zv
}
}
-static inline zend_result fetch_obj_prop(zval **result, zval *op1, zval *op2) {
+static inline zend_result fetch_obj_prop(zval **result, const zval *op1, const zval *op2) {
switch (Z_TYPE_P(op2)) {
case IS_STRING:
*result = zend_symtable_find(Z_ARR_P(op1), Z_STR_P(op2));
@@ -597,7 +597,7 @@ static inline zend_result fetch_obj_prop(zval **result, zval *op1, zval *op2) {
}
}
-static inline zend_result ct_eval_fetch_obj(zval *result, zval *op1, zval *op2) {
+static inline zend_result ct_eval_fetch_obj(zval *result, const zval *op1, const zval *op2) {
if (IS_PARTIAL_OBJECT(op1)) {
zval *value;
if (fetch_obj_prop(&value, op1, op2) == SUCCESS && value && !IS_BOT(value)) {
@@ -608,7 +608,7 @@ static inline zend_result ct_eval_fetch_obj(zval *result, zval *op1, zval *op2)
return FAILURE;
}
-static inline zend_result ct_eval_isset_obj(zval *result, uint32_t extended_value, zval *op1, zval *op2) {
+static inline zend_result ct_eval_isset_obj(zval *result, uint32_t extended_value, const zval *op1, const zval *op2) {
if (IS_PARTIAL_OBJECT(op1)) {
zval *value;
if (fetch_obj_prop(&value, op1, op2) == FAILURE) {
@@ -664,7 +664,7 @@ static inline zend_result ct_eval_assign_obj(zval *result, zval *value, const zv
}
}
-static inline zend_result ct_eval_incdec(zval *result, uint8_t opcode, zval *op1) {
+static inline zend_result ct_eval_incdec(zval *result, uint8_t opcode, const zval *op1) {
/* As of PHP 8.3 with the warning/deprecation notices any type other than int/double/null will emit a diagnostic
if (Z_TYPE_P(op1) == IS_ARRAY || IS_PARTIAL_ARRAY(op1)) {
return FAILURE;
@@ -691,7 +691,7 @@ static inline zend_result ct_eval_incdec(zval *result, uint8_t opcode, zval *op1
return SUCCESS;
}
-static inline void ct_eval_type_check(zval *result, uint32_t type_mask, zval *op1) {
+static inline void ct_eval_type_check(zval *result, uint32_t type_mask, const zval *op1) {
uint32_t type = Z_TYPE_P(op1);
if (type == PARTIAL_ARRAY) {
type = IS_ARRAY;
@@ -701,14 +701,14 @@ static inline void ct_eval_type_check(zval *result, uint32_t type_mask, zval *op
ZVAL_BOOL(result, (type_mask >> type) & 1);
}
-static inline zend_result ct_eval_in_array(zval *result, uint32_t extended_value, zval *op1, zval *op2) {
- HashTable *ht;
+static inline zend_result ct_eval_in_array(zval *result, uint32_t extended_value, zval *op1, const zval *op2) {
+
bool res;
if (Z_TYPE_P(op2) != IS_ARRAY) {
return FAILURE;
}
- ht = Z_ARRVAL_P(op2);
+ const HashTable *ht = Z_ARRVAL_P(op2);
if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
res = zend_hash_exists(ht, Z_STR_P(op1));
} else if (extended_value) {
@@ -736,7 +736,7 @@ static inline zend_result ct_eval_in_array(zval *result, uint32_t extended_value
return SUCCESS;
}
-static inline zend_result ct_eval_array_key_exists(zval *result, zval *op1, zval *op2) {
+static inline zend_result ct_eval_array_key_exists(zval *result, const zval *op1, const zval *op2) {
zval *value;
if (Z_TYPE_P(op2) != IS_ARRAY && !IS_PARTIAL_ARRAY(op2)) {
@@ -756,7 +756,7 @@ static inline zend_result ct_eval_array_key_exists(zval *result, zval *op1, zval
return SUCCESS;
}
-static bool can_ct_eval_func_call(zend_function *func, zend_string *name, uint32_t num_args, zval **args) {
+static bool can_ct_eval_func_call(const zend_function *func, const zend_string *name, uint32_t num_args, zval **args) {
/* Precondition: func->type == ZEND_INTERNAL_FUNCTION, this is a global function */
/* Functions setting ZEND_ACC_COMPILE_TIME_EVAL (@compile-time-eval) must always produce the same result for the same arguments,
* and have no dependence on global state (such as locales). It is okay if they throw
@@ -793,7 +793,7 @@ static bool can_ct_eval_func_call(zend_function *func, zend_string *name, uint32
static inline zend_result ct_eval_func_call_ex(
zend_op_array *op_array, zval *result, zend_function *func, uint32_t num_args, zval **args) {
uint32_t i;
- zend_string *name = func->common.function_name;
+ const zend_string *name = func->common.function_name;
if (num_args == 1 && Z_TYPE_P(args[0]) == IS_STRING &&
zend_optimizer_eval_special_func_call(result, name, Z_STR_P(args[0])) == SUCCESS) {
return SUCCESS;
@@ -1772,9 +1772,9 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
}
}
-static zval *value_from_type_and_range(sccp_ctx *ctx, int var_num, zval *tmp) {
- zend_ssa *ssa = ctx->scdf.ssa;
- zend_ssa_var_info *info = &ssa->var_info[var_num];
+static zval *value_from_type_and_range(const sccp_ctx *ctx, int var_num, zval *tmp) {
+ const zend_ssa *ssa = ctx->scdf.ssa;
+ const zend_ssa_var_info *info = &ssa->var_info[var_num];
if (info->type & MAY_BE_UNDEF) {
return NULL;
@@ -1826,9 +1826,9 @@ static zval *value_from_type_and_range(sccp_ctx *ctx, int var_num, zval *tmp) {
/* Returns whether there is a successor */
static void sccp_mark_feasible_successors(
scdf_ctx *scdf,
- int block_num, zend_basic_block *block,
- zend_op *opline, zend_ssa_op *ssa_op) {
- sccp_ctx *ctx = (sccp_ctx *) scdf;
+ int block_num, const zend_basic_block *block,
+ zend_op *opline, const zend_ssa_op *ssa_op) {
+ const sccp_ctx *ctx = (const sccp_ctx *) scdf;
zval *op1, zv;
uint32_t s;
@@ -1917,10 +1917,10 @@ static void sccp_mark_feasible_successors(
|| (opline->opcode == ZEND_MATCH && (type == IS_LONG || type == IS_STRING));
if (correct_type) {
- zend_op_array *op_array = scdf->op_array;
- zend_ssa *ssa = scdf->ssa;
- HashTable *jmptable = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, opline->op2.constant));
- zval *jmp_zv = type == IS_LONG
+ const zend_op_array *op_array = scdf->op_array;
+ const zend_ssa *ssa = scdf->ssa;
+ const HashTable *jmptable = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, opline->op2.constant));
+ const zval *jmp_zv = type == IS_LONG
? zend_hash_index_find(jmptable, Z_LVAL_P(op1))
: zend_hash_find(jmptable, Z_STR_P(op1));
int target;
@@ -1933,8 +1933,8 @@ static void sccp_mark_feasible_successors(
scdf_mark_edge_feasible(scdf, block_num, target);
return;
} else if (strict_comparison) {
- zend_op_array *op_array = scdf->op_array;
- zend_ssa *ssa = scdf->ssa;
+ const zend_op_array *op_array = scdf->op_array;
+ const zend_ssa *ssa = scdf->ssa;
int target = ssa->cfg.map[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)];
scdf_mark_edge_feasible(scdf, block_num, target);
return;
@@ -1951,7 +1951,7 @@ static void sccp_mark_feasible_successors(
scdf_mark_edge_feasible(scdf, block_num, block->successors[s]);
}
-static void join_hash_tables(HashTable *ret, HashTable *ht1, HashTable *ht2)
+static void join_hash_tables(HashTable *ret, const HashTable *ht1, const HashTable *ht2)
{
zend_ulong index;
zend_string *key;
@@ -1974,7 +1974,7 @@ static void join_hash_tables(HashTable *ret, HashTable *ht1, HashTable *ht2)
} ZEND_HASH_FOREACH_END();
}
-static zend_result join_partial_arrays(zval *a, zval *b)
+static zend_result join_partial_arrays(zval *a, const zval *b)
{
zval ret;
@@ -1991,7 +1991,7 @@ static zend_result join_partial_arrays(zval *a, zval *b)
return SUCCESS;
}
-static zend_result join_partial_objects(zval *a, zval *b)
+static zend_result join_partial_objects(zval *a, const zval *b)
{
zval ret;
@@ -2007,7 +2007,7 @@ static zend_result join_partial_objects(zval *a, zval *b)
return SUCCESS;
}
-static void join_phi_values(zval *a, zval *b, bool escape) {
+static void join_phi_values(zval *a, const zval *b, bool escape) {
if (IS_BOT(a) || IS_TOP(b)) {
return;
}
@@ -2040,12 +2040,12 @@ static void join_phi_values(zval *a, zval *b, bool escape) {
}
static void sccp_visit_phi(scdf_ctx *scdf, const zend_ssa_phi *phi) {
- sccp_ctx *ctx = (sccp_ctx *) scdf;
- zend_ssa *ssa = scdf->ssa;
+ const sccp_ctx *ctx = (const sccp_ctx *) scdf;
+ const zend_ssa *ssa = scdf->ssa;
ZEND_ASSERT(phi->ssa_var >= 0);
if (!IS_BOT(&ctx->values[phi->ssa_var])) {
- zend_basic_block *block = &ssa->cfg.blocks[phi->block];
- int *predecessors = &ssa->cfg.predecessors[block->predecessor_offset];
+ const zend_basic_block *block = &ssa->cfg.blocks[phi->block];
+ const int *predecessors = &ssa->cfg.predecessors[block->predecessor_offset];
zval result;
MAKE_TOP(&result);
@@ -2083,10 +2083,10 @@ static void sccp_visit_phi(scdf_ctx *scdf, const zend_ssa_phi *phi) {
}
/* Call instruction -> remove opcodes that are part of the call */
-static int remove_call(sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op)
+static int remove_call(const sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op)
{
- zend_ssa *ssa = ctx->scdf.ssa;
- zend_op_array *op_array = ctx->scdf.op_array;
+ const zend_ssa *ssa = ctx->scdf.ssa;
+ const zend_op_array *op_array = ctx->scdf.op_array;
zend_call_info *call;
ZEND_ASSERT(ctx->call_map);
@@ -2121,7 +2121,7 @@ static int remove_call(sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op)
* we need to collect.
* d) The ordinary DCE pass cannot collect construction of dead non-escaping arrays and objects.
*/
-static uint32_t try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var, zval *value)
+static uint32_t try_remove_definition(const sccp_ctx *ctx, int var_num, const zend_ssa_var *var, zval *value)
{
zend_ssa *ssa = ctx->scdf.ssa;
zend_op_array *op_array = ctx->scdf.op_array;
@@ -2369,9 +2369,9 @@ static uint32_t try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *
/* This will try to replace uses of SSA variables we have determined to be constant. Not all uses
* can be replaced, because some instructions don't accept constant operands or only accept them
* if they have a certain type. */
-static uint32_t replace_constant_operands(sccp_ctx *ctx) {
- zend_ssa *ssa = ctx->scdf.ssa;
- zend_op_array *op_array = ctx->scdf.op_array;
+static uint32_t replace_constant_operands(const sccp_ctx *ctx) {
+ const zend_ssa *ssa = ctx->scdf.ssa;
+ const zend_op_array *op_array = ctx->scdf.op_array;
int i;
zval tmp;
uint32_t removed_ops = 0;
@@ -2379,7 +2379,7 @@ static uint32_t replace_constant_operands(sccp_ctx *ctx) {
/* We iterate the variables backwards, so we can eliminate sequences like INIT_ROPE
* and INIT_ARRAY. */
for (i = ssa->vars_count - 1; i >= op_array->last_var; i--) {
- zend_ssa_var *var = &ssa->vars[i];
+ const zend_ssa_var *var = &ssa->vars[i];
zval *value;
int use;
@@ -2437,7 +2437,7 @@ static uint32_t replace_constant_operands(sccp_ctx *ctx) {
}
static void sccp_context_init(zend_optimizer_ctx *ctx, sccp_ctx *sccp,
- zend_ssa *ssa, zend_op_array *op_array, zend_call_info **call_map) {
+ const zend_ssa *ssa, const zend_op_array *op_array, zend_call_info **call_map) {
int i;
sccp->call_map = call_map;
sccp->values = zend_arena_alloc(&ctx->arena, sizeof(zval) * ssa->vars_count);
@@ -2486,7 +2486,7 @@ uint32_t sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_array
int i, first = 1;
for (i = op_array->last_var; i < ssa->vars_count; i++) {
- zval *zv = &sccp.values[i];
+ const zval *zv = &sccp.values[i];
if (IS_TOP(zv) || IS_BOT(zv)) {
continue;
diff --git a/Zend/Optimizer/scdf.c b/Zend/Optimizer/scdf.c
index 31f40a7ed9f..57bbbde3bc7 100644
--- a/Zend/Optimizer/scdf.c
+++ b/Zend/Optimizer/scdf.c
@@ -116,7 +116,7 @@ void scdf_solve(scdf_ctx *scdf, const char *name) {
while ((i = zend_bitset_pop_first(scdf->instr_worklist, scdf->instr_worklist_len)) >= 0) {
int block_num = ssa->cfg.map[i];
if (zend_bitset_in(scdf->executable_blocks, block_num)) {
- zend_basic_block *block = &ssa->cfg.blocks[block_num];
+ const zend_basic_block *block = &ssa->cfg.blocks[block_num];
zend_op *opline = &scdf->op_array->opcodes[i];
zend_ssa_op *ssa_op = &ssa->ops[i];
if (opline->opcode == ZEND_OP_DATA) {
@@ -136,7 +136,7 @@ void scdf_solve(scdf_ctx *scdf, const char *name) {
while ((i = zend_bitset_pop_first(scdf->block_worklist, scdf->block_worklist_len)) >= 0) {
/* This block is now live. Interpret phis and instructions in it. */
- zend_basic_block *block = &ssa->cfg.blocks[i];
+ const zend_basic_block *block = &ssa->cfg.blocks[i];
const zend_ssa_block *ssa_block = &ssa->blocks[i];
DEBUG_PRINT("Pop block %d from worklist\n", i);
diff --git a/Zend/Optimizer/scdf.h b/Zend/Optimizer/scdf.h
index d7bee4b7381..50390a1c132 100644
--- a/Zend/Optimizer/scdf.h
+++ b/Zend/Optimizer/scdf.h
@@ -39,8 +39,8 @@ typedef struct _scdf_ctx {
void (*visit_phi)(
struct _scdf_ctx *scdf, const zend_ssa_phi *phi);
void (*mark_feasible_successors)(
- struct _scdf_ctx *scdf, int block_num, zend_basic_block *block,
- zend_op *opline, zend_ssa_op *ssa_op);
+ struct _scdf_ctx *scdf, int block_num, const zend_basic_block *block,
+ zend_op *opline, const zend_ssa_op *ssa_op);
} handlers;
} scdf_ctx;
diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c
index 2e6cc70ec25..c2f6098a812 100644
--- a/Zend/Optimizer/zend_inference.c
+++ b/Zend/Optimizer/zend_inference.c
@@ -2095,9 +2095,8 @@ static void emit_type_narrowing_warning(const zend_op_array *op_array, const zen
ZEND_API uint32_t ZEND_FASTCALL zend_array_type_info(const zval *zv)
{
- HashTable *ht = Z_ARRVAL_P(zv);
+ const HashTable *ht = Z_ARRVAL_P(zv);
uint32_t tmp = MAY_BE_ARRAY;
- zend_string *str;
zval *val;
if (Z_REFCOUNTED_P(zv)) {
@@ -2114,7 +2113,7 @@ ZEND_API uint32_t ZEND_FASTCALL zend_array_type_info(const zval *zv)
tmp |= 1 << (Z_TYPE_P(val) + MAY_BE_ARRAY_SHIFT);
} ZEND_HASH_FOREACH_END();
} else {
- ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(ht, str, val) {
+ ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(ht, const zend_string *str, val) {
if (str) {
tmp |= MAY_BE_ARRAY_STRING_HASH;
} else {
@@ -4199,7 +4198,7 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend
j = zend_bitset_first(worklist, worklist_len);
zend_bitset_excl(worklist, j);
if (ssa_vars[j].definition_phi) {
- zend_ssa_phi *p = ssa_vars[j].definition_phi;
+ const zend_ssa_phi *p = ssa_vars[j].definition_phi;
if (p->pi >= 0) {
zend_class_entry *ce = ssa_var_info[p->sources[0]].ce;
bool is_instanceof = ssa_var_info[p->sources[0]].is_instanceof;
@@ -4746,7 +4745,7 @@ static void zend_mark_cv_references(const zend_op_array *op_array, const zend_sc
{
int var, def;
const zend_op *opline;
- zend_arg_info *arg_info;
+ const zend_arg_info *arg_info;
uint32_t worklist_len = zend_bitset_len(ssa->vars_count);
zend_bitset worklist;
ALLOCA_FLAG(use_heap);
@@ -4840,7 +4839,7 @@ static void zend_mark_cv_references(const zend_op_array *op_array, const zend_sc
ssa->var_info[var].type |= MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
if (ssa->vars[var].phi_use_chain) {
- zend_ssa_phi *p = ssa->vars[var].phi_use_chain;
+ const zend_ssa_phi *p = ssa->vars[var].phi_use_chain;
do {
if (!(ssa->var_info[p->ssa_var].type & MAY_BE_REF)) {
zend_bitset_incl(worklist, p->ssa_var);
@@ -4852,7 +4851,7 @@ static void zend_mark_cv_references(const zend_op_array *op_array, const zend_sc
if (ssa->vars[var].use_chain >= 0) {
int use = ssa->vars[var].use_chain;
FOREACH_USE(&ssa->vars[var], use) {
- zend_ssa_op *op = ssa->ops + use;
+ const zend_ssa_op *op = ssa->ops + use;
if (op->op1_use == var && op->op1_def >= 0) {
if (!(ssa->var_info[op->op1_def].type & MAY_BE_REF)) {
/* Unset breaks references (outside global scope). */
@@ -5231,7 +5230,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
return 1;
}
- zend_property_info *prop_info =
+ const zend_property_info *prop_info =
zend_hash_find_ptr(&ce->properties_info, prop_name);
if (prop_info) {
if (ZEND_TYPE_IS_SET(prop_info->type)) {
diff --git a/Zend/Optimizer/zend_optimizer.c b/Zend/Optimizer/zend_optimizer.c
index d437a3fbe53..6d5b5f541a9 100644
--- a/Zend/Optimizer/zend_optimizer.c
+++ b/Zend/Optimizer/zend_optimizer.c
@@ -1475,14 +1475,13 @@ static void zend_optimize_op_array(zend_op_array *op_array,
static void zend_adjust_fcall_stack_size(const zend_op_array *op_array, const zend_optimizer_ctx *ctx)
{
- zend_function *func;
zend_op *opline;
opline = op_array->opcodes;
const zend_op* end = opline + op_array->last;
while (opline < end) {
if (opline->opcode == ZEND_INIT_FCALL) {
- func = zend_hash_find_ptr(
+ const zend_function *func = zend_hash_find_ptr(
&ctx->script->function_table,
Z_STR_P(RT_CONSTANT(opline, opline->op2)));
if (func) {
diff --git a/Zend/Optimizer/zend_optimizer_internal.h b/Zend/Optimizer/zend_optimizer_internal.h
index d01df56260b..6add0f76bc0 100644
--- a/Zend/Optimizer/zend_optimizer_internal.h
+++ b/Zend/Optimizer/zend_optimizer_internal.h
@@ -124,6 +124,6 @@ void zend_optimizer_migrate_jump(const zend_op_array *op_array, zend_op *new_opl
void zend_optimizer_shift_jump(const zend_op_array *op_array, zend_op *opline, const uint32_t *shiftlist);
uint32_t sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_array, zend_ssa *ssa, zend_call_info **call_map);
int dce_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *optimizer_ctx, zend_ssa *ssa, bool reorder_dtor_effects);
-zend_result zend_ssa_escape_analysis(const zend_script *script, zend_op_array *op_array, zend_ssa *ssa);
+zend_result zend_ssa_escape_analysis(const zend_script *script, const zend_op_array *op_array, const zend_ssa *ssa);
#endif