Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Zend/Optimizer/block_pass.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
break;
case ZEND_IS_SMALLER:
if (opline->opcode == ZEND_BOOL_NOT) {
uint8_t tmp_type;
zend_operand_type tmp_type;
uint32_t tmp;

src->opcode = ZEND_IS_SMALLER_OR_EQUAL;
Expand All @@ -593,7 +593,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
break;
case ZEND_IS_SMALLER_OR_EQUAL:
if (opline->opcode == ZEND_BOOL_NOT) {
uint8_t tmp_type;
zend_operand_type tmp_type;
uint32_t tmp;

src->opcode = ZEND_IS_SMALLER;
Expand Down
2 changes: 1 addition & 1 deletion Zend/Optimizer/dce.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ static inline bool is_free_of_live_var(const context *ctx, const zend_op *opline
static bool dce_instr(const context *ctx, zend_op *opline, zend_ssa_op *ssa_op) {
const zend_ssa *ssa = ctx->ssa;
int free_var = -1;
uint8_t free_var_type;
zend_operand_type free_var_type;

if (opline->opcode == ZEND_NOP) {
return false;
Expand Down
2 changes: 1 addition & 1 deletion Zend/Optimizer/ssa_integrity.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ static inline bool is_in_successors(zend_basic_block *block, int check) {
return false;
}

static inline bool is_var_type(uint8_t type) {
static inline bool is_var_type(zend_operand_type type) {
return (type & (IS_CV|IS_VAR|IS_TMP_VAR)) != 0;
}

Expand Down
4 changes: 2 additions & 2 deletions Zend/Optimizer/zend_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ static void zend_dump_unused_op(const zend_op *opline, znode_op op, uint32_t fla
}
}

ZEND_API void zend_dump_var(const zend_op_array *op_array, uint8_t var_type, uint32_t var_num)
ZEND_API void zend_dump_var(const zend_op_array *op_array, zend_operand_type var_type, uint32_t var_num)
{
if (var_type == IS_CV && var_num < op_array->last_var) {
fprintf(stderr, "CV%d($%s)", var_num, op_array->vars[var_num]->val);
Expand Down Expand Up @@ -382,7 +382,7 @@ static void zend_dump_ssa_var_info(const zend_ssa *ssa, int ssa_var_num, uint32_
dump_flags);
}

ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int ssa_var_num, uint8_t var_type, uint32_t var_num, uint32_t dump_flags)
ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int ssa_var_num, zend_operand_type var_type, uint32_t var_num, uint32_t dump_flags)
{
if (ssa_var_num >= 0) {
fprintf(stderr, "#%d.", ssa_var_num);
Expand Down
4 changes: 2 additions & 2 deletions Zend/Optimizer/zend_dump.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ void zend_dump_dominators(const zend_op_array *op_array, const zend_cfg *cfg);
void zend_dump_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zend_dfg *dfg);
void zend_dump_phi_placement(const zend_op_array *op_array, const zend_ssa *ssa);
void zend_dump_ssa_variables(const zend_op_array *op_array, const zend_ssa *ssa, uint32_t dump_flags);
ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int ssa_var_num, uint8_t var_type, uint32_t var_num, uint32_t dump_flags);
ZEND_API void zend_dump_var(const zend_op_array *op_array, uint8_t var_type, uint32_t var_num);
ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int ssa_var_num, zend_operand_type var_type, uint32_t var_num, uint32_t dump_flags);
ZEND_API void zend_dump_var(const zend_op_array *op_array, zend_operand_type var_type, uint32_t var_num);
void zend_dump_op_array_name(const zend_op_array *op_array);
void zend_dump_const(const zval *zv);
void zend_dump_ht(const HashTable *ht);
Expand Down
6 changes: 3 additions & 3 deletions Zend/Optimizer/zend_inference.c
Original file line number Diff line number Diff line change
Expand Up @@ -2134,7 +2134,7 @@ ZEND_API uint32_t ZEND_FASTCALL zend_array_type_info(const zval *zv)
}


ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, bool write, bool insert)
ZEND_API uint32_t zend_array_element_type(uint32_t t1, zend_operand_type op_type, bool write, bool insert)
{
uint32_t tmp = 0;

Expand Down Expand Up @@ -2196,7 +2196,7 @@ ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, bool wri
}

static uint32_t assign_dim_array_result_type(
uint32_t arr_type, uint32_t dim_type, uint32_t value_type, uint8_t dim_op_type) {
uint32_t arr_type, uint32_t dim_type, uint32_t value_type, zend_operand_type dim_op_type) {
uint32_t tmp = 0;
/* Only add key type if we have a value type. We want to maintain the invariant that a
* key type exists iff a value type exists even in dead code that may use empty types. */
Expand Down Expand Up @@ -2244,7 +2244,7 @@ static uint32_t assign_dim_array_result_type(
}

static uint32_t assign_dim_result_type(
uint32_t arr_type, uint32_t dim_type, uint32_t value_type, uint8_t dim_op_type) {
uint32_t arr_type, uint32_t dim_type, uint32_t value_type, zend_operand_type dim_op_type) {
uint32_t tmp = arr_type & ~(MAY_BE_RC1|MAY_BE_RCN);

if (arr_type & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) {
Expand Down
2 changes: 1 addition & 1 deletion Zend/Optimizer/zend_inference.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ ZEND_API void zend_ssa_find_false_dependencies(const zend_op_array *op_array, co
ZEND_API void zend_ssa_find_sccs(const zend_op_array *op_array, zend_ssa *ssa);
ZEND_API zend_result zend_ssa_inference(zend_arena **raena, const zend_op_array *op_array, const zend_script *script, zend_ssa *ssa, zend_long optimization_level);

ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, bool write, bool insert);
ZEND_API uint32_t zend_array_element_type(uint32_t t1, zend_operand_type op_type, bool write, bool insert);

ZEND_API bool zend_inference_propagate_range(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op* ssa_op, int var, zend_ssa_range *tmp);

Expand Down
2 changes: 1 addition & 1 deletion Zend/Optimizer/zend_optimizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ bool zend_optimizer_update_op2_const(zend_op_array *op_array,

bool zend_optimizer_replace_by_const(zend_op_array *op_array,
zend_op *opline,
uint8_t type,
zend_operand_type type,
uint32_t var,
zval *val)
{
Expand Down
2 changes: 1 addition & 1 deletion Zend/Optimizer/zend_optimizer_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ bool zend_optimizer_update_op2_const(zend_op_array *op_array,
zval *val);
bool zend_optimizer_replace_by_const(zend_op_array *op_array,
zend_op *opline,
uint8_t type,
zend_operand_type type,
uint32_t var,
zval *val);
zend_op *zend_optimizer_get_loop_var_def(const zend_op_array *op_array, zend_op *free_opline);
Expand Down
8 changes: 6 additions & 2 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@

typedef struct _zend_loop_var {
uint8_t opcode;
uint8_t var_type;
zend_operand_type var_type;
uint32_t var_num;
uint32_t try_catch_offset;
} zend_loop_var;
Expand Down Expand Up @@ -6394,6 +6394,10 @@ static void zend_compile_void_cast(znode *result, const zend_ast *ast)
case IS_CONST:
zend_do_free(&expr_node);
break;
case IS_UNUSED:
case IS_CV:
/* Nothing to free */
break;
}
}

Expand Down Expand Up @@ -7262,7 +7266,7 @@ static void zend_compile_match(znode *result, zend_ast *ast)
case_node.u.op.var = get_temporary_variable();

uint32_t num_conds = count_match_conds(arms);
uint8_t can_use_jumptable = can_match_use_jumptable(arms);
bool can_use_jumptable = can_match_use_jumptable(arms);
bool uses_jumptable = can_use_jumptable && num_conds >= 2;
HashTable *jumptable = NULL;
uint32_t *jmpnz_opnums = NULL;
Expand Down
31 changes: 17 additions & 14 deletions Zend/zend_compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@
#include "zend_frameless_function.h"
#include "zend_property_hooks.h"

/* Assign as specific bits so that one can quickly check types via a bit operation */
C23_ENUM(zend_operand_type, uint8_t) {
IS_UNUSED = 0, /* Unused operand */
IS_CONST = (1<<0),
IS_TMP_VAR = (1<<1),
IS_VAR = (1<<2),
IS_CV = (1<<3), /* Compiled variable */
};

/* Used in zend_op.result_type for smart branch instructions */
#define IS_SMART_BRANCH_JMPZ (1<<4)
#define IS_SMART_BRANCH_JMPNZ (1<<5)

#define SET_UNUSED(op) do { \
op ## _type = IS_UNUSED; \
op.num = (uint32_t) -1; \
Expand Down Expand Up @@ -81,7 +94,7 @@ typedef union _znode_op {
} znode_op;

typedef struct _znode { /* used only during compilation */
uint8_t op_type;
zend_operand_type op_type;
uint8_t flag;
union {
znode_op op;
Expand Down Expand Up @@ -142,9 +155,9 @@ struct _zend_op {
uint32_t extended_value;
uint32_t lineno;
uint8_t opcode; /* Opcodes defined in Zend/zend_vm_opcodes.h */
uint8_t op1_type; /* IS_UNUSED, IS_CONST, IS_TMP_VAR, IS_VAR, IS_CV */
uint8_t op2_type; /* IS_UNUSED, IS_CONST, IS_TMP_VAR, IS_VAR, IS_CV */
uint8_t result_type; /* IS_UNUSED, IS_CONST, IS_TMP_VAR, IS_VAR, IS_CV */
zend_operand_type op1_type;
zend_operand_type op2_type;
uint8_t result_type; /* zend_operand_type value with possible IS_SMART_BRANCH_JMPZ or IS_SMART_BRANCH_JMPNZ flag added */
#ifdef ZEND_VERIFY_TYPE_INFERENCE
uint32_t op1_use_type;
uint32_t op2_use_type;
Expand Down Expand Up @@ -861,16 +874,6 @@ static_assert(ZEND_MM_ALIGNED_SIZE(sizeof(zval)) == sizeof(zval),
#define ZEND_OP_ARRAY_EXTENSION(op_array, handle) \
((void**)RUN_TIME_CACHE(op_array))[handle]

#define IS_UNUSED 0 /* Unused operand */
#define IS_CONST (1<<0)
#define IS_TMP_VAR (1<<1)
#define IS_VAR (1<<2)
#define IS_CV (1<<3) /* Compiled variable */

/* Used for result.type of smart branch instructions */
#define IS_SMART_BRANCH_JMPZ (1<<4)
#define IS_SMART_BRANCH_JMPNZ (1<<5)

#define ZEND_EXTRA_VALUE 1

#include "zend_globals.h"
Expand Down
40 changes: 22 additions & 18 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_W(uint32_t var EXECUTE_D
return ret;
}

static zend_always_inline zval *_get_zval_ptr_tmpvarcv(int op_type, znode_op node, int type EXECUTE_DATA_DC)
static zend_always_inline zval *_get_zval_ptr_tmpvarcv(zend_operand_type op_type, znode_op node, int type EXECUTE_DATA_DC)
{
if (op_type & (IS_TMP_VAR|IS_VAR)) {
if (op_type == IS_TMP_VAR) {
Expand All @@ -429,7 +429,7 @@ static zend_always_inline zval *_get_zval_ptr_tmpvarcv(int op_type, znode_op nod
}
}

static zend_always_inline zval *_get_zval_ptr(int op_type, znode_op node, int type EXECUTE_DATA_DC OPLINE_DC)
static zend_always_inline zval *_get_zval_ptr(zend_operand_type op_type, znode_op node, int type EXECUTE_DATA_DC OPLINE_DC)
{
if (op_type & (IS_TMP_VAR|IS_VAR)) {
if (!ZEND_DEBUG || op_type == IS_VAR) {
Expand All @@ -449,7 +449,7 @@ static zend_always_inline zval *_get_zval_ptr(int op_type, znode_op node, int ty
}
}

static zend_always_inline zval *_get_op_data_zval_ptr_r(int op_type, znode_op node EXECUTE_DATA_DC OPLINE_DC)
static zend_always_inline zval *_get_op_data_zval_ptr_r(zend_operand_type op_type, znode_op node EXECUTE_DATA_DC OPLINE_DC)
{
if (op_type & (IS_TMP_VAR|IS_VAR)) {
if (!ZEND_DEBUG || op_type == IS_VAR) {
Expand All @@ -469,7 +469,7 @@ static zend_always_inline zval *_get_op_data_zval_ptr_r(int op_type, znode_op no
}
}

static zend_always_inline ZEND_ATTRIBUTE_UNUSED zval *_get_zval_ptr_deref(int op_type, znode_op node, int type EXECUTE_DATA_DC OPLINE_DC)
static zend_always_inline ZEND_ATTRIBUTE_UNUSED zval *_get_zval_ptr_deref(zend_operand_type op_type, znode_op node, int type EXECUTE_DATA_DC OPLINE_DC)
{
if (op_type & (IS_TMP_VAR|IS_VAR)) {
if (op_type == IS_TMP_VAR) {
Expand All @@ -489,7 +489,7 @@ static zend_always_inline ZEND_ATTRIBUTE_UNUSED zval *_get_zval_ptr_deref(int op
}
}

static zend_always_inline ZEND_ATTRIBUTE_UNUSED zval *_get_op_data_zval_ptr_deref_r(int op_type, znode_op node EXECUTE_DATA_DC OPLINE_DC)
static zend_always_inline ZEND_ATTRIBUTE_UNUSED zval *_get_op_data_zval_ptr_deref_r(zend_operand_type op_type, znode_op node EXECUTE_DATA_DC OPLINE_DC)
{
if (op_type & (IS_TMP_VAR|IS_VAR)) {
if (op_type == IS_TMP_VAR) {
Expand All @@ -509,7 +509,7 @@ static zend_always_inline ZEND_ATTRIBUTE_UNUSED zval *_get_op_data_zval_ptr_dere
}
}

static zend_always_inline zval *_get_zval_ptr_undef(int op_type, znode_op node, int type EXECUTE_DATA_DC OPLINE_DC)
static zend_always_inline zval *_get_zval_ptr_undef(zend_operand_type op_type, znode_op node, int type EXECUTE_DATA_DC OPLINE_DC)
{
if (op_type & (IS_TMP_VAR|IS_VAR)) {
if (!ZEND_DEBUG || op_type == IS_VAR) {
Expand Down Expand Up @@ -539,7 +539,7 @@ static zend_always_inline zval *_get_zval_ptr_ptr_var(uint32_t var EXECUTE_DATA_
return ret;
}

static inline zval *_get_zval_ptr_ptr(int op_type, znode_op node, int type EXECUTE_DATA_DC)
static inline zval *_get_zval_ptr_ptr(zend_operand_type op_type, znode_op node, int type EXECUTE_DATA_DC)
{
if (op_type == IS_CV) {
return _get_zval_ptr_cv(node.var, type EXECUTE_DATA_CC);
Expand All @@ -549,31 +549,31 @@ static inline zval *_get_zval_ptr_ptr(int op_type, znode_op node, int type EXECU
}
}

static inline ZEND_ATTRIBUTE_UNUSED zval *_get_obj_zval_ptr(int op_type, znode_op op, int type EXECUTE_DATA_DC OPLINE_DC)
static inline ZEND_ATTRIBUTE_UNUSED zval *_get_obj_zval_ptr(zend_operand_type op_type, znode_op op, int type EXECUTE_DATA_DC OPLINE_DC)
{
if (op_type == IS_UNUSED) {
return &EX(This);
}
return get_zval_ptr(op_type, op, type);
}

static inline ZEND_ATTRIBUTE_UNUSED zval *_get_obj_zval_ptr_deref(int op_type, znode_op op, int type EXECUTE_DATA_DC OPLINE_DC)
static inline ZEND_ATTRIBUTE_UNUSED zval *_get_obj_zval_ptr_deref(zend_operand_type op_type, znode_op op, int type EXECUTE_DATA_DC OPLINE_DC)
{
if (op_type == IS_UNUSED) {
return &EX(This);
}
return get_zval_ptr_deref(op_type, op, type);
}

static inline ZEND_ATTRIBUTE_UNUSED zval *_get_obj_zval_ptr_undef(int op_type, znode_op op, int type EXECUTE_DATA_DC OPLINE_DC)
static inline ZEND_ATTRIBUTE_UNUSED zval *_get_obj_zval_ptr_undef(zend_operand_type op_type, znode_op op, int type EXECUTE_DATA_DC OPLINE_DC)
{
if (op_type == IS_UNUSED) {
return &EX(This);
}
return get_zval_ptr_undef(op_type, op, type);
}

static inline ZEND_ATTRIBUTE_UNUSED zval *_get_obj_zval_ptr_ptr(int op_type, znode_op node, int type EXECUTE_DATA_DC)
static inline ZEND_ATTRIBUTE_UNUSED zval *_get_obj_zval_ptr_ptr(zend_operand_type op_type, znode_op node, int type EXECUTE_DATA_DC)
{
if (op_type == IS_UNUSED) {
return &EX(This);
Expand Down Expand Up @@ -3541,9 +3541,9 @@ static zend_never_inline bool zend_handle_fetch_obj_flags(
static zend_always_inline void zend_fetch_property_address(
zval *result,
const zval *container,
uint32_t container_op_type,
zend_operand_type container_op_type,
const zval *prop_ptr,
uint32_t prop_op_type,
zend_operand_type prop_op_type,
void **cache_slot,
int type,
uint32_t flags,
Expand Down Expand Up @@ -3696,9 +3696,9 @@ static zend_always_inline void zend_fetch_property_address(

static zend_always_inline void zend_assign_to_property_reference(
const zval *container,
uint32_t container_op_type,
zend_operand_type container_op_type,
const zval *prop_ptr,
uint32_t prop_op_type,
zend_operand_type prop_op_type,
zval *value_ptr
OPLINE_DC EXECUTE_DATA_DC
) {
Expand Down Expand Up @@ -4088,7 +4088,7 @@ static zend_always_inline void i_zval_ptr_dtor_noref(zval *zval_ptr) {
}
}

ZEND_API zval* zend_assign_to_typed_ref_ex(zval *variable_ptr, zval *orig_value, uint8_t value_type, bool strict, zend_refcounted **garbage_ptr)
ZEND_API zval* zend_assign_to_typed_ref_ex(zval *variable_ptr, zval *orig_value, zend_operand_type value_type, bool strict, zend_refcounted **garbage_ptr)
{
bool ret;
zval value;
Expand Down Expand Up @@ -4123,7 +4123,7 @@ ZEND_API zval* zend_assign_to_typed_ref_ex(zval *variable_ptr, zval *orig_value,
return variable_ptr;
}

ZEND_API zval* zend_assign_to_typed_ref(zval *variable_ptr, zval *orig_value, uint8_t value_type, bool strict)
ZEND_API zval* zend_assign_to_typed_ref(zval *variable_ptr, zval *orig_value, zend_operand_type value_type, bool strict)
{
zend_refcounted *garbage = NULL;
zval *result = zend_assign_to_typed_ref_ex(variable_ptr, orig_value, value_type, strict, &garbage);
Expand Down Expand Up @@ -5960,7 +5960,11 @@ static zend_always_inline zend_execute_data *_zend_vm_stack_push_call_frame(uint
/* This callback disables optimization of "vm_stack_data" variable in VM */
ZEND_API void (ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data) = NULL;

/* We ignore tautological compares for the zend_operand_type cases as the VM will generate many IS_* == IS_*
* that will be optimized out by the compiled */
ZEND_DIAGNOSTIC_IGNORED_START("-Wtautological-compare")
#include "zend_vm_execute.h"
ZEND_DIAGNOSTIC_IGNORED_END

ZEND_API zend_result zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)
{
Expand All @@ -5982,7 +5986,7 @@ ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode)
return zend_user_opcode_handlers[opcode];
}

ZEND_API zval *zend_get_zval_ptr(const zend_op *opline, int op_type, const znode_op *node, const zend_execute_data *execute_data)
ZEND_API zval *zend_get_zval_ptr(const zend_op *opline, zend_operand_type op_type, const znode_op *node, const zend_execute_data *execute_data)
{
zval *ret;

Expand Down
Loading
Loading