Skip to content
Merged
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/zend_opcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -829,13 +829,13 @@ static bool keeps_op1_alive(zend_op *opline) {
if (opline->opcode == ZEND_CASE
|| opline->opcode == ZEND_CASE_STRICT
|| opline->opcode == ZEND_SWITCH_LONG
|| opline->opcode == ZEND_SWITCH_STRING
|| opline->opcode == ZEND_MATCH
|| opline->opcode == ZEND_FETCH_LIST_R
|| opline->opcode == ZEND_COPY_TMP) {
return 1;
}
ZEND_ASSERT(opline->opcode != ZEND_SWITCH_STRING
&& opline->opcode != ZEND_FE_FETCH_R
ZEND_ASSERT(opline->opcode != ZEND_FE_FETCH_R
&& opline->opcode != ZEND_FE_FETCH_RW
&& opline->opcode != ZEND_FETCH_LIST_W
&& opline->opcode != ZEND_VERIFY_RETURN_TYPE
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_operators.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ static zend_always_inline const void *zend_memrchr(const void *s, int c, size_t
}

for (e = (const unsigned char *)s + n - 1; e >= (const unsigned char *)s; e--) {
if (*e == (const unsigned char)c) {
if (*e == (unsigned char)c) {
return (const void *)e;
}
}
Expand Down
7 changes: 4 additions & 3 deletions ext/intl/breakiterator/breakiterator_iterators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ extern "C" {
}

static zend_class_entry *IntlPartsIterator_ce_ptr;
static zend_object_handlers IntlPartsIterator_handlers;

/* BreakIterator's iterator */

Expand Down Expand Up @@ -87,7 +86,8 @@ static const zend_object_iterator_funcs breakiterator_iterator_funcs = {
NULL,
_breakiterator_move_forward,
_breakiterator_rewind,
zoi_with_current_invalidate_current
zoi_with_current_invalidate_current,
NULL, /* get_gc */
};

U_CFUNC zend_object_iterator *_breakiterator_get_iterator(
Expand Down Expand Up @@ -200,7 +200,8 @@ static const zend_object_iterator_funcs breakiterator_parts_it_funcs = {
_breakiterator_parts_get_current_key,
_breakiterator_parts_move_forward,
_breakiterator_parts_rewind,
zoi_with_current_invalidate_current
zoi_with_current_invalidate_current,
NULL, /* get_gc */
};

void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
Expand Down
1 change: 0 additions & 1 deletion ext/intl/breakiterator/breakiterator_methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ static void _breakiter_no_args_ret_int32(
int32_t (BreakIterator::*func)(),
INTERNAL_FUNCTION_PARAMETERS)
{
char *msg;
BREAKITER_METHOD_INIT_VARS;
object = ZEND_THIS;

Expand Down
4 changes: 2 additions & 2 deletions ext/intl/breakiterator/codepointiterator_internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ using icu::UCharCharacterIterator;
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CodePointBreakIterator)

CodePointBreakIterator::CodePointBreakIterator()
: BreakIterator(), fCharIter(NULL), lastCodePoint(U_SENTINEL)
: BreakIterator(), lastCodePoint(U_SENTINEL), fCharIter(NULL)
{
UErrorCode uec = UErrorCode();
this->fText = utext_openUChars(NULL, NULL, 0, &uec);
}

CodePointBreakIterator::CodePointBreakIterator(const PHP::CodePointBreakIterator &other)
: BreakIterator(other), fText(NULL), fCharIter(NULL), lastCodePoint(U_SENTINEL)
: BreakIterator(other), fText(NULL), lastCodePoint(U_SENTINEL), fCharIter(NULL)
{
*this = other;
}
Expand Down
2 changes: 1 addition & 1 deletion ext/intl/calendar/gregoriancalendar_methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static void _php_intlgregcal_constructor_body(
INTERNAL_FUNCTION_PARAMETERS, bool is_constructor)
{
zval *tz_object = NULL;
zval args_a[6] = {0},
zval args_a[6],
*args = &args_a[0];
char *locale = NULL;
size_t locale_len;
Expand Down
3 changes: 2 additions & 1 deletion ext/intl/common/common_enum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ static const zend_object_iterator_funcs string_enum_object_iterator_funcs = {
NULL,
string_enum_current_move_forward,
string_enum_rewind,
zoi_with_current_invalidate_current
zoi_with_current_invalidate_current,
NULL, /* get_gc */
};

U_CFUNC void IntlIterator_from_StringEnumeration(StringEnumeration *se, zval *object)
Expand Down
4 changes: 2 additions & 2 deletions ext/opcache/jit/zend_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -3121,7 +3121,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
}
if (!zend_jit_assign_dim_op(&dasm_state, opline,
OP1_INFO(), OP1_DEF_INFO(), OP1_REG_ADDR(), OP2_INFO(),
OP1_DATA_INFO(), OP1_DATA_RANGE(),
OP1_DATA_INFO(), OP1_DATA_RANGE(), IS_UNKNOWN,
zend_may_throw(opline, ssa_op, op_array, ssa))) {
goto jit_failure;
}
Expand All @@ -3134,7 +3134,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
break;
}
if (!zend_jit_assign_dim(&dasm_state, opline,
OP1_INFO(), OP1_REG_ADDR(), OP2_INFO(), OP1_DATA_INFO(),
OP1_INFO(), OP1_REG_ADDR(), OP2_INFO(), OP1_DATA_INFO(), IS_UNKNOWN,
zend_may_throw(opline, ssa_op, op_array, ssa))) {
goto jit_failure;
}
Expand Down
24 changes: 15 additions & 9 deletions ext/opcache/jit/zend_jit_arm64.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -4882,7 +4882,7 @@ static int zend_jit_concat(dasm_State **Dst, const zend_op *opline, uint32_t op1
return zend_jit_concat_helper(Dst, opline, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, res_addr, may_throw);
}

static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_op *opline, uint32_t type, uint32_t op1_info, uint32_t op2_info, const void *found_exit_addr, const void *not_found_exit_addr, const void *exit_addr)
static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_op *opline, uint32_t type, uint32_t op1_info, uint32_t op2_info, uint8_t dim_type, const void *found_exit_addr, const void *not_found_exit_addr, const void *exit_addr)
/* Labels: 1,2,3,4,5 */
{
zend_jit_addr op2_addr = OP2_ADDR();
Expand Down Expand Up @@ -4944,6 +4944,12 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
}
packed_loaded = 1;
}

if (dim_type == IS_UNDEF && type == BP_VAR_W) {
/* don't generate "fast" code for packed array */
packed_loaded = 0;
}

if (packed_loaded) {
| // ZEND_HASH_INDEX_FIND(ht, hval, retval, num_undef);
if (op1_info & MAY_BE_ARRAY_NUMERIC_HASH) {
Expand Down Expand Up @@ -5111,7 +5117,7 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
if (packed_loaded) {
| IF_NOT_Z_TYPE REG0, IS_UNDEF, >8, TMP1w
}
if (!(op1_info & MAY_BE_ARRAY_KEY_LONG) || (op1_info & MAY_BE_ARRAY_NUMERIC_HASH) || packed_loaded) {
if (!(op1_info & MAY_BE_ARRAY_KEY_LONG) || (op1_info & MAY_BE_ARRAY_NUMERIC_HASH) || packed_loaded || dim_type == IS_UNDEF) {
|2:
|4:
if (!op2_loaded) {
Expand Down Expand Up @@ -5701,7 +5707,7 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
return 1;
}

static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, uint32_t val_info, int may_throw)
static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, uint32_t val_info, uint8_t dim_type, int may_throw)
{
zend_jit_addr op2_addr, op3_addr, res_addr;

Expand Down Expand Up @@ -5799,7 +5805,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
uint32_t var_info = zend_array_element_type(op1_info, opline->op1_type, 0, 0);
zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_REG0, 0);

if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_W, op1_info, op2_info, NULL, NULL, NULL)) {
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_W, op1_info, op2_info, dim_type, NULL, NULL, NULL)) {
return 0;
}

Expand Down Expand Up @@ -5912,7 +5918,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
return 1;
}

static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, uint32_t op1_def_info, zend_jit_addr op1_addr, uint32_t op2_info, uint32_t op1_data_info, zend_ssa_range *op1_data_range, int may_throw)
static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, uint32_t op1_def_info, zend_jit_addr op1_addr, uint32_t op2_info, uint32_t op1_data_info, zend_ssa_range *op1_data_range, uint8_t dim_type, int may_throw)
{
zend_jit_addr op2_addr, op3_addr, var_addr;

Expand Down Expand Up @@ -6016,7 +6022,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
var_info |= MAY_BE_RC1;
}

if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, NULL, NULL, NULL)) {
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, dim_type, NULL, NULL, NULL)) {
return 0;
}

Expand Down Expand Up @@ -10915,7 +10921,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst,
}
}
| GET_ZVAL_LVAL ZREG_FCARG1, op1_addr, TMP1
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, (opline->opcode != ZEND_FETCH_DIM_IS) ? BP_VAR_R : BP_VAR_IS, op1_info, op2_info, res_exit_addr, not_found_exit_addr, exit_addr)) {
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, (opline->opcode != ZEND_FETCH_DIM_IS) ? BP_VAR_R : BP_VAR_IS, op1_info, op2_info, IS_UNKNOWN, res_exit_addr, not_found_exit_addr, exit_addr)) {
return 0;
}
}
Expand Down Expand Up @@ -11217,7 +11223,7 @@ static int zend_jit_fetch_dim(dasm_State **Dst,
ZEND_UNREACHABLE();
}

if (!zend_jit_fetch_dimension_address_inner(Dst, opline, type, op1_info, op2_info, NULL, NULL, NULL)) {
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, type, op1_info, op2_info, IS_UNKNOWN, NULL, NULL, NULL)) {
return 0;
}

Expand Down Expand Up @@ -11338,7 +11344,7 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst,
not_found_exit_addr = exit_addr;
}
}
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_JIT_IS, op1_info, op2_info, found_exit_addr, not_found_exit_addr, NULL)) {
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_JIT_IS, op1_info, op2_info, IS_UNKNOWN, found_exit_addr, not_found_exit_addr, NULL)) {
return 0;
}

Expand Down
3 changes: 3 additions & 0 deletions ext/opcache/jit/zend_jit_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ typedef enum _zend_jit_trace_op {
ZEND_JIT_TRACE_VM,
ZEND_JIT_TRACE_OP1_TYPE,
ZEND_JIT_TRACE_OP2_TYPE,
ZEND_JIT_TRACE_VAL_INFO,
ZEND_JIT_TRACE_INIT_CALL,
ZEND_JIT_TRACE_DO_ICALL,
ZEND_JIT_TRACE_ENTER,
Expand All @@ -451,6 +452,8 @@ typedef enum _zend_jit_trace_op {
#define IS_TRACE_REFERENCE (1<<5)
#define IS_TRACE_INDIRECT (1<<6)

#define IS_TRACE_TYPE_MASK 0xf

#define ZEND_JIT_TRACE_FAKE_INIT_CALL 0x00000100
#define ZEND_JIT_TRACE_RETURN_VALUE_USED 0x00000100

Expand Down
35 changes: 31 additions & 4 deletions ext/opcache/jit/zend_jit_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -975,7 +975,7 @@ static int find_return_ssa_var(zend_jit_trace_rec *p, zend_ssa_op *ssa_op)
}
}
return -1;
} else if (p->op == ZEND_JIT_TRACE_OP1_TYPE || p->op == ZEND_JIT_TRACE_OP2_TYPE) {
} else if (p->op >= ZEND_JIT_TRACE_OP1_TYPE && p->op <= ZEND_JIT_TRACE_VAL_INFO) {
/*skip */
} else {
return -1;
Expand All @@ -1001,7 +1001,7 @@ static const zend_op *zend_jit_trace_find_init_fcall_op(zend_jit_trace_rec *p, c
return p->opline;
}
return NULL;
} else if (p->op == ZEND_JIT_TRACE_OP1_TYPE || p->op == ZEND_JIT_TRACE_OP2_TYPE) {
} else if (p->op >= ZEND_JIT_TRACE_OP1_TYPE && p->op <= ZEND_JIT_TRACE_VAL_INFO) {
/*skip */
} else {
return NULL;
Expand Down Expand Up @@ -1597,6 +1597,9 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
op2_ce = (zend_class_entry*)(p+1)->ce;
p++;
}
if ((p+1)->op == ZEND_JIT_TRACE_VAL_INFO) {
p++;
}

switch (opline->opcode) {
case ZEND_ASSIGN_OP:
Expand Down Expand Up @@ -4072,6 +4075,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
uint8_t op3_type = p->op3_type;
uint8_t orig_op1_type = op1_type;
uint8_t orig_op2_type = op2_type;
uint8_t val_type = IS_UNKNOWN;
bool op1_indirect;
zend_class_entry *op1_ce = NULL;
zend_class_entry *op2_ce = NULL;
Expand All @@ -4098,6 +4102,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
op2_ce = (zend_class_entry*)(p+1)->ce;
p++;
}
if ((p+1)->op == ZEND_JIT_TRACE_VAL_INFO) {
val_type = (p+1)->op1_type;
p++;
}

frame_flags = 0;

Expand Down Expand Up @@ -4387,7 +4395,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
op1_def_info = OP1_DEF_INFO();
if (!zend_jit_assign_dim_op(&dasm_state, opline,
op1_info, op1_def_info, op1_addr, op2_info,
op1_data_info, OP1_DATA_RANGE(),
op1_data_info, OP1_DATA_RANGE(), val_type,
zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, op2_info))) {
goto jit_failure;
}
Expand Down Expand Up @@ -4636,7 +4644,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
op1_data_info = OP1_DATA_INFO();
CHECK_OP1_DATA_TRACE_TYPE();
if (!zend_jit_assign_dim(&dasm_state, opline,
op1_info, op1_addr, op2_info, op1_data_info,
op1_info, op1_addr, op2_info, op1_data_info, val_type,
zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, op2_info))) {
goto jit_failure;
}
Expand Down Expand Up @@ -6919,6 +6927,25 @@ static void zend_jit_dump_trace(zend_jit_trace_rec *trace_buffer, zend_ssa *tssa
fprintf(stderr, " op3(%s%s)", ref, type);
}
}
if ((p+1)->op == ZEND_JIT_TRACE_VAL_INFO) {
uint8_t val_type;
const char *type;

if (op1_type == IS_UNKNOWN && op2_type == IS_UNKNOWN && op3_type == IS_UNKNOWN) {
fprintf(stderr, " ;");
}
p++;
val_type = p->op1_type;

if (val_type == IS_UNDEF) {
type = "undef";
} else if (val_type == IS_REFERENCE) {
type = "ref";
} else {
type = zend_get_type_by_const(val_type);
}
fprintf(stderr, " val(%s)", type);
}
fprintf(stderr, "\n");
idx++;

Expand Down
57 changes: 57 additions & 0 deletions ext/opcache/jit/zend_jit_vm_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,63 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
TRACE_RECORD(ZEND_JIT_TRACE_OP2_TYPE, 0, ce2);
}

switch (opline->opcode) {
case ZEND_FETCH_DIM_R:
case ZEND_FETCH_DIM_W:
case ZEND_FETCH_DIM_RW:
case ZEND_FETCH_DIM_IS:
case ZEND_FETCH_DIM_FUNC_ARG:
case ZEND_FETCH_DIM_UNSET:
case ZEND_FETCH_LIST_R:
case ZEND_FETCH_LIST_W:
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_DIM_OP:
case ZEND_UNSET_DIM:
case ZEND_ISSET_ISEMPTY_DIM_OBJ:
if (opline->op1_type == IS_CONST) {
zval *arr = RT_CONSTANT(opline, opline->op1);
op1_type = Z_TYPE_P(arr);
}
if ((op1_type & IS_TRACE_TYPE_MASK) == IS_ARRAY
&& opline->op2_type != IS_UNDEF) {
zval *arr, *dim, *val;
uint8_t val_type = IS_UNDEF;

if (opline->op2_type == IS_CONST) {
dim = RT_CONSTANT(opline, opline->op2);
} else {
dim = EX_VAR(opline->op2.var);
}

if (Z_TYPE_P(dim) == IS_LONG || Z_TYPE_P(dim) == IS_STRING) {
if (opline->op1_type == IS_CONST) {
arr = RT_CONSTANT(opline, opline->op1);
} else {
arr = EX_VAR(opline->op1.var);
}
if (Z_TYPE_P(arr) == IS_INDIRECT) {
arr = Z_INDIRECT_P(arr);
}
if (Z_TYPE_P(arr) == IS_REFERENCE) {
arr = Z_REFVAL_P(arr);
}
ZEND_ASSERT(Z_TYPE_P(arr) == IS_ARRAY);
if (Z_TYPE_P(dim) == IS_LONG) {
val = zend_hash_index_find(Z_ARRVAL_P(arr), Z_LVAL_P(dim));
} else /*if Z_TYPE_P(dim) == IS_STRING)*/ {
val = zend_symtable_find(Z_ARRVAL_P(arr), Z_STR_P(dim));
}
if (val) {
val_type = Z_TYPE_P(val);
}
TRACE_RECORD_VM(ZEND_JIT_TRACE_VAL_INFO, NULL, val_type, 0, 0);
}
}
break;
default:
break;
}

if (opline->opcode == ZEND_DO_FCALL
|| opline->opcode == ZEND_DO_ICALL
|| opline->opcode == ZEND_DO_UCALL
Expand Down
Loading